当我不提供方法名时,为什么Ruby调用`call`方法?

时间:2013-10-04 19:52:52

标签: ruby

给出以下模块:

module Foo
  def self.call
    'foo'
  end
end

我当然希望以下工作:

puts Foo.call  # outputs "foo"

但是,我没想到这会起作用:

puts Foo.()    # outputs "foo"

显然,当方法名称停止时,Ruby假定我想调用call方法。这在哪里记录,为什么它会这样?

2 个答案:

答案 0 :(得分:11)

Proc#call

  

调用块,使用接近方法调用语义的东西将块的参数设置为params中的值。如果将多个值传递给只需要一个的proc(之前将这些参数静默转换为数组),则会生成警告。 请注意,prc。()使用给定的参数调用prc.call()。隐藏“呼叫”是一种语法糖。

我做了一些研究,发现方法#()是方法#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)

请在此处查看 Matz 所说的So compromise with object.() syntax introduced in 1.9...

答案 1 :(得分:0)

显然,正如Arup所说,这是前一段时间引入的语法糖,可能是因为Proc对象更容易使用的唯一原因。 (您不必明确地调用它们,但可以改为prc.())。

我还得出结论,这绝对是Ruby 1.9+功能。如果我将JRuby切换到1.8模式,我会改为:

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

所以,在Ruby 1.9的更改日志中的某个地方,如果有人真的想从洞穴中挖掘它,可能会发现... :)