tags:

views:

150

answers:

3

I just wondered whether there is any good reason for or even an advantage in having to invoke Procs using proc.call(args) in Ruby, which makes higher-order function syntax much more verbose and less intuitive.

Why not just proc(args)? Why draw a distinction between functions, lambdas and blocks? Basically, it's all the same thing so why this confusing syntax? Or is there any point for it I don't realize?

+1  A: 

You want to be able to pass it around without calling it, right? Requiring that it be explicitly called allows that. Otherwise, every time you tried to use the proc as a parameter, you would end up calling it.

Telemachus
To expand: In Ruby, parentheses for method calls are optional, so the interpreter can't tell the difference between `proc`, or just passing the closure around, and `proc` as a synonym for `proc()`.
mipadi
What he said :)
Telemachus
+6  A: 

In ruby you can have a local variable and a method that are both named foo. Assuming the method is private, the only way to call it would be foo(args) (self.foo(args) would not work for private methods which can't have an explicit receiver). If ruby would allow to overload the () operator, so that the foo in foo(bar) can be a variable, there would be no way to call the private method foo, when there is also a local variable named foo.

Note that with features like define_method and method_missing, it is not always possible to avoid situations where you have methods and local variables of the same name.

sepp2k
To split hairs, there's one private method that ruby allows an explicit receiver for: self.foo=(args) , to distinguish between creating a local variable and calling the method.
Andrew Grimm
+9  A: 

You need some way to distinguish between calling the Proc and passing it around.

In Python and ECMAScript, it's simple: with parentheses it's a call, without it's not. In Ruby, leaving off the parentheses is also a call, therefore, there must be some other way to distinguish.

In Ruby 1.8, Proc#call and its alias Proc#[] serve that distinction. As of Ruby 1.9, there is a new allowed method name () which gets called like this obj.() and Proc#() is also an alias for Proc#call.

So, you can call a Proc like this:

  • foo.call(1, 2, 3)
  • foo[1, 2, 3]
  • foo.(1, 2, 3)

And you can even also define () for your own classes.

BTW: the same problem is also why you have to use the method method to get a hold of a method object.

Jörg W Mittag