Почему Ruby вызывает метод `call`, когда я не предоставляю имя метода?

Учитывая следующий модуль:

module Foo
  def self.call
    'foo'
  end
end

Я бы, конечно, ожидал, что следующее будет работать:

puts Foo.call  # outputs "foo"

Однако я не ожидал, что это сработает:

puts Foo.()    # outputs "foo"

По-видимому, когда имя метода прекращено, Ruby предполагает, что я хочу вызвать метод call. Где это документировано и почему оно ведет себя таким образом?

Ответ 1

Proc#call:

Вызывает блок, устанавливая параметры блоков для значений в параметрах, используя что-то близкое к семантике вызова метода. Генерирует предупреждение, если нескольким значениям передается proc, который ожидает только один (ранее это молча преобразовывало параметры в массив). Обратите внимание, что prc.() вызывает prc.call() с указанными параметрами. Его синтаксический сахар, чтобы скрыть "вызов".

Я провел некоторое исследование, и найденный метод #() является синтаксическим suger метода #call. Посмотрите на ошибку, как показано ниже:

module Foo
  def self.bar
    12
  end
end
Foo.()
#undefined method `call' for Foo:Module (NoMethodError)

Поскольку OP определил метод #call в классе Foo, Foo#call вызывается в попытке Foo.().

Вот еще несколько примеров:

"ab".method(:size).() # => 2
"ab".method(:size).call # => 2
"ab".() # undefined method `call' for "ab":String (NoMethodError)

См. здесь, что сказал Мац Итак, компромисс с синтаксисом object.(), введенным в версии 1.9...

Ответ 2

По-видимому, как говорит Аруп, это синтаксический сахар, введенный некоторое время назад, возможно, для единственной причины облегчения работы с объектами Proc. (Вам не нужно явно называть их, но может просто сделать prc.()).

Я также пришел к выводу, что это определенно функция Ruby 1.9+. Если я переключу режим JRuby на 1.8, я получаю это вместо:

SyntaxError: spam.rb:12: syntax error, unexpected tLPAREN2

Итак, где-то в списках изменений для Ruby 1.9 можно, вероятно, найти, если кто-то действительно хочет выкопать его из пещер...:)