I recently came across some code using a method call consisting of the format object.(arg1, arg2)
without seeing a good explanation of how it works. See this sample code:
class TestServiceObject def call 'method' end end TestServiceObject.new.() # => 'method'
What's the term for this kind of shorthand?
As a general convention, << in Ruby means "append", i.e. it appends its argument to its receiver and then returns the receiver. So, for Array it appends the argument to the array, for String it performs string concatenation, for Set it adds the argument to the set, for IO it writes to the file descriptor, and so on.
In Ruby, the === operator is used to test equality within a when clause of a case statement. In other languages, the above is true. To my knowledge, Ruby doesn't have true operators, they are all methods which are invoked on the LHS of the expression, passing in the RHS of the expression.
<< and + are methods (in Ruby, santa << ' Nick' is the same as santa. <<(' Nick') ), while += is a shortcut combining assignment and the concatenation method.
The dot-parentheses notation is a shorthand way for passing arguments to the implicit call
method on a Ruby object:
foo = lambda {|bar| puts bar} foo.call('baz') #=> baz foo.('baz') foo.call('baz') === foo.('baz') #=> true
Also note that the following notations are also valid (and equivalent) invocations of the call
method:
foo['baz'] #=> baz foo::('baz') #=> baz
In your example, you're explicitly overriding the call
method on the TestServiceObject
class such that it returns the string 'method'
when called. Accordingly, you can explicitly override the the call
method to accept arguments:
class TestServiceObject def call(foo=nil) foo || 'method' end end TestServiceObject.new.() #=> method TestServicesObject.new.('bar') #=> bar
UPDATE:
As commenter @LoganSerman duly notes, the shorthand operator appears to work on anything that responds to call
, which is validated in part by the following example:
m = 12.method("+") m.call(3) #=> 15 m.(3) #=> 15
UPDATE 2:
As commenter @Stefan also points out from the documentation on Proc#call
:
prc.() invokes prc.call() with the parameters given. It’s a syntax sugar to hide “call”.
obj.(args)
is just a feature provided through the parser. Not technically an alias, but it simply has the same effect as invoking obj.call(args)
on an object that defines the call
method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With