我最近遇到了一些使用由格式组成的方法调用的代码,但object.(arg1, arg2)
没有很好地解释它是如何工作的。请参阅此示例代码:
class TestServiceObject
def call
'method'
end
end
TestServiceObject.new.()
# => 'method'
这种速记的术语是什么?
我最近遇到了一些使用由格式组成的方法调用的代码,但object.(arg1, arg2)
没有很好地解释它是如何工作的。请参阅此示例代码:
class TestServiceObject
def call
'method'
end
end
TestServiceObject.new.()
# => 'method'
这种速记的术语是什么?
点括号表示法是一种将参数传递给call
Ruby 对象的隐式方法的简写方式:
foo = lambda {|bar| puts bar}
foo.call('baz')
#=> baz
foo.('baz')
foo.call('baz') === foo.('baz')
#=> true
另请注意,以下符号也是该方法的有效(和等效)调用call
:
foo['baz']
#=> baz
foo::('baz')
#=> baz
在您的示例中,您明确覆盖了类call
上的方法,以便在调用时返回字符串。因此,您可以显式覆盖该方法以接受参数:TestServiceObject
'method'
call
class TestServiceObject
def call(foo=nil)
foo || 'method'
end
end
TestServiceObject.new.()
#=> method
TestServicesObject.new.('bar')
#=> bar
更新:
正如评论者@LoganSerman适当指出的那样,速记运算符似乎可以处理任何响应call
的内容,以下示例部分验证了这一点:
m = 12.method("+")
m.call(3)
#=> 15
m.(3)
#=> 15
更新 2:
正如评论者@Stefan还从以下文档中Proc#call
指出的那样:
prc.() 使用给定的参数调用 prc.call()。这是隐藏“调用”的语法糖。
obj.(args)
只是通过解析器提供的一个功能。从技术上讲,它不是别名,但它与调用定义方法obj.call(args)
的对象具有相同的效果。call
foo.(bar, baz)
被解释为
foo.call(bar, baz)
就像
foo + bar
被解释为
foo.+(bar)
或者
foo[bar, baz] = quux
被解释为
foo.[]=(bar, baz, quux)
目的是使调用类函数的对象看起来类似于调用方法:
foo.(bar, baz) # function
foo(bar, baz) # method
尽管在这个问题的其他答案中声称,它与“隐式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"