From: John Woods Date: 2007-10-13T03:22:08+09:00 Subject: Re: Syntax error when redefining >> operator to take a block >> I'm trying to redefine the >> operator for a particular class such that >> it takes a block as its argument. It works if I invoke the redifined >> >> operator using "." syntax, but causes a syntax error otherwise. >> >> [...snip...] >> >> Any pointers? Thanks. > > Redefining operator behavior cannot change Ruby's syntax. >> is with > a block is just not valid Ruby syntax - as you have seen. I don't understand why it's invalid syntax. I'm new to Ruby and am looking to better understand. Please consider these two different definitions of >> def >>(arg) .... def >>(&arg) .... and these two different invocations of >> c >> { } c.>> { } In the following example, the first invocation works with the first definition, and the second with the second. However the first/second invocation doesn't work second/first definition, respectively. class C def >>(arg) puts arg.class end end c = C.new c >> { } # outputs 'Hash' #c.>> { } # syntax error: wrong number of args (0 for 1) class C def >>(&arg) puts arg.class end end c.>> { } # outputs 'Proc' #c >> { } # syntax error: wrong number of args (1 for 0) It seems that if the operator is invoked with only optional whitespace between the receiver "c" and the operator ">>" then ruby interprets the following { ... } to be a hash, and if the operator is invoked with a "." then ruby interprets { ... } to be a proc. And this appears to be regardless of what's actually between the braces, or regardless of how the argument to >> is defined (ie with or without the "&"). I'm wondering why ruby doesn't instead interpret { ... } to be either a hash or a proc based on what's inside the braces. For example, { 1 => "one" } is a hash, and { |x| x + x } is a proc. It seems to me this distinction should be made by what's between the braces, and not whether there's a " " or "." between the receiver and the operator. Then, if there's a mismatch between what's being passed and the operator definition, I would expect an error. So is this an area where Ruby's parsing could be improved to enable passing a block to an operator (without having to use "." to invoke the operator)? Or, am I misunderstanding something? Any insight would be appreciated.