Ruby的.()运算符是如何工作的?

fru*_*ose 31 ruby methods syntax service-object

我最近遇到了一些使用方法调用的代码,该方法调用由格式组成,但object.(arg1, arg2) 没有很好地解释它是如何工作的.请参阅以下示例代码:

class TestServiceObject
  def call
    'method'
  end
end

TestServiceObject.new.()
# => 'method'
Run Code Online (Sandbox Code Playgroud)

这种速记的术语是什么?

zea*_*soi 39

点括号表示法是将参数传递给callRuby对象上的隐式方法的简便方法:

foo = lambda {|bar| puts bar}

foo.call('baz')
#=> baz
foo.('baz')

foo.call('baz') === foo.('baz')
#=> true
Run Code Online (Sandbox Code Playgroud)

另请注意,以下表示法也是该call方法的有效(和等效)调用:

foo['baz']
#=> baz
foo::('baz')
#=> baz
Run Code Online (Sandbox Code Playgroud)

在您的示例中,您将显式覆盖call上的方法,TestServiceObject以便'method'在调用时返回字符串.因此,您可以显式覆盖call接受参数的方法:

class TestServiceObject
  def call(foo=nil)
    foo || 'method'
  end
end

TestServiceObject.new.()
#=> method
TestServicesObject.new.('bar')
#=> bar
Run Code Online (Sandbox Code Playgroud)

更新:

正如评论者@LoganSerman正式指出的那样,简写操作符似乎可以处理响应的任何内容call,这部分通过以下示例进行验证:

m = 12.method("+")

m.call(3)
#=> 15
m.(3)
#=> 15
Run Code Online (Sandbox Code Playgroud)

更新2:

评论者@Stefan也从文档中Proc#call指出:

prc.()使用给定的参数调用prc.call().隐藏"呼叫"是一种语法糖.


Jör*_*tag 6

foo.(bar, baz)
Run Code Online (Sandbox Code Playgroud)

被解释为

foo.call(bar, baz)
Run Code Online (Sandbox Code Playgroud)

就像

foo + bar
Run Code Online (Sandbox Code Playgroud)

被解释为

foo.+(bar)
Run Code Online (Sandbox Code Playgroud)

或者

foo[bar, baz] = quux
Run Code Online (Sandbox Code Playgroud)

被解释为

foo.[]=(bar, baz, quux)
Run Code Online (Sandbox Code Playgroud)

目的是使调用类似函数的对象看起来类似于调用方法:

foo.(bar, baz) # function
foo(bar, baz)  # method
Run Code Online (Sandbox Code Playgroud)

call尽管在这个问题的其他答案中声称,它与“隐式方法”(Ruby 甚至没有式方法,只有 Scala 有)或索引运算符无关。

索引运算符被转换为不同的方法调用 ( []) 而不是对 的调用call

o = Object.new

def o.call(*args); "`call` called with #{args.join(', ')}" end

o.(42)
# => "`call` called with 42"

o[42]
# NoMethodError: undefined method `[]' for #<Object:0xdeadbeefc0ffee>

def o.[](*args);   "`[]` called with #{args.join(', ')}"   end

o[42]
# => "`[]` called with 42"
Run Code Online (Sandbox Code Playgroud)


Kon*_*che 5

obj.(args)只是通过解析器提供的功能。从技术上讲,这不是别名,但它与调用定义obj.call(args)该方法的对象具有相同的效果call