Есть разница между:: и. при вызове методов класса в Ruby?
Простой вопрос, но тот, который мне интересен... есть ли функциональная разница между двумя командами?
String::class
String.class
Они оба делают то, что я ожидаю, то есть возвращают Class
- но в чем разница между использованием ::
и .
?
Я заметил, что в тех классах, которые имеют константы, IR-автозаполнение возвращает константы в качестве доступных параметров, когда вы нажимаете вкладку после ::
, но не после .
, но я не знаю, в чем причина это...
Ответы
Ответ 1
Оператор .
в основном говорит "отправьте это сообщение объекту". В вашем примере он вызывает этот конкретный член. Оператор ::
"сверлит" до области, определенной слева от оператора, а затем вызывает член, определенный в правой части оператора.
Когда вы используете ::
, вы должны ссылаться на определенные члены. При использовании .
вы просто отправляете сообщение этому объекту. Поскольку это сообщение может быть чем угодно, автозаполнение не работает для .
, пока оно выполняется для ::
.
Ответ 2
На самом деле автозаполнение работает для .
. Параметры завершения можно найти, вызвав #methods
объекта. Вы можете это увидеть сами, переопределив Object.methods
:
>> def Object.methods; ["foo", "bar"]; end
=> nil
>> Object.[TAB]
Object.foo Object.bar
>> Object.
Обратите внимание, что это работает только тогда, когда выражение слева от .
является литералом. В противном случае получение объекта для вызова #methods
on будет включать оценку левой стороны, которая может иметь побочные эффекты. Вы сами это видите и сами:
[continuing from above...]
>> def Object.baz; Object; end
=> nil
>> Object.baz.[TAB]
Display all 1022 possibilities? (y or n)
Добавим метод #baz
в Object
, который возвращает Object
. Затем мы автоматически завершаем, чтобы получить методы, которые мы можем назвать Object.baz
. Если IRB называется Object.baz.methods
, он получит то же самое, что и Object.methods
. Вместо этого IRB имеет 1022 предложения. Я не уверен, откуда они взялись, но это явно общий список, который на самом деле не основан на контексте.
Оператор ::
(также) используется для получения констант модуля, а .
- нет. Поэтому HTTP
будет отображаться в завершении для Net::
, но не для Net.
. Net.HTTP
неверен, но Net::HTTP
есть.