Подтвердить что ты не робот

Есть разница между:: и. при вызове методов класса в Ruby?

Простой вопрос, но тот, который мне интересен... есть ли функциональная разница между двумя командами?

String::class
String.class

Они оба делают то, что я ожидаю, то есть возвращают Class - но в чем разница между использованием :: и .?

Я заметил, что в тех классах, которые имеют константы, IR-автозаполнение возвращает константы в качестве доступных параметров, когда вы нажимаете вкладку после ::, но не после ., но я не знаю, в чем причина это...

4b9b3361

Ответ 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 есть.