rubymethodssyntaxservice-object

How does Ruby's .() operator work?


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?


Solution

  • 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”.