From: James Coglan Date: 2009-03-20T19:15:39+09:00 Subject: Re: Passing a named function instead of a code block? --00504502bad097924b04658a3c90 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit 2009/3/20 7stud -- > James Coglan wrote: > > 2009/3/20 7stud -- > > > >> > >> (ArgumentError) > >> from r1test.rb:8 > >> > >> > >> Why does ruby make you use the tortured syntax: > >> > >> &method(:square1) > >> > >> for a method vs. the easier syntax for a Proc object? > > > > > > > > square2 is a variable name (ie. something you've made an assignment to), > > it's just a reference to the lambda object. However, square1 is a method > > and > > Ruby allows calling methods without parens, so 'square1' is actually > > interpreted as a method call to square1 with no arguments. Therefore, to > > grab a method as an object without calling it, we need to use > > method(:square1). > > Ok. But there is a certain amount of hypocrisy in that explanation > Look here: > > &square1 > :square1 > > In the first expression there is a method call, and in the second there > isn't. Yet, you could describe both those lines as: a method name > preceded by some symbol. Yes, it probably looks that way. To see the difference it helps to know how Ruby is parsed. :square1 is an atomic unit representing the symbol whose name is 'square1'. ":" is not an operator, it is part of the syntax for symbols. However, "&" is an operator responsible for casting between procs and blocks. The expression '&square1' should be read '&( square1 )', that is we call square1 and cast the result of that using '&'. The same applies to 'method'. 'method' is a method that takes a symbol/string and returns the Method object with that name in the current scope. 'method(square1)' would be interpreted as a call to square1, passing the result to 'method'. So, '&square1' throws an error because you're calling a method with insufficient arguments. '&:square1' would try to cast a symbol to a proc, which if you're using ActiveSupport would return the block { |object| object.square1 }. '&square2' is fine as square2 is just a variable referring to a proc. Likewise, '&method(:square1)' is fine because method(:square1) is a Method object, which can be cast to a block. -- James Coglan http://github.com/jcoglan --00504502bad097924b04658a3c90--