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

Mat*_*ins 11 ruby

给出以下模块:

module Foo
  def self.call
    'foo'
  end
end
Run Code Online (Sandbox Code Playgroud)

我当然希望以下工作:

puts Foo.call  # outputs "foo"
Run Code Online (Sandbox Code Playgroud)

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

puts Foo.()    # outputs "foo"
Run Code Online (Sandbox Code Playgroud)

显然当方法名称被取消时,Ruby假定我想调用该call方法.这在哪里记录,为什么它会这样?

Aru*_*hit 12

Proc#call:

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

我做了一些研究,发现方法#()是该方法的一种语法.#call看看如下错误:

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

由于OP #call在模块Foo类中定义了方法,Foo#call因此在尝试时调用Foo.().

这是一些更多的例子:

"ab".method(:size).() # => 2
"ab".method(:size).call # => 2
"ab".() # undefined method `call' for "ab":String (NoMethodError)
Run Code Online (Sandbox Code Playgroud)

在这里看看Matz所说的那么妥协的对象.()语法在1.9中引入...

  • 由于Ruby是动态类型的,所以Ruby几乎不可能定义仅适用于一种类型的语法糖.语法糖同样适用于所有类型,尽管在运行时对象的类型可能没有意义. (2认同)