On 12.10.2007 20:22, John W. wrote:
c >> { }
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 cannot be different because - as I have said before - a method /
operator (re-)definition cannot change the syntax of the language. For
syntax it is completely irrelevant how you define a method / operator.
Here are some examples:
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self.>> {}’
[]
#Proc:0x00000000@-e:1
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self.>>({})’
[{}]
nil
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self.>>(){}’
[]
#Proc:0x00000000@-e:1
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self >> {}’
[{}]
nil
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self.>> {|x|}’
[]
#Proc:0x00000000@-e:1
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self.>>() {|x|}’
[]
#Proc:0x00000000@-e:1
robert@fussel ~
$ ruby -e ‘def self.>>(*a,&b) p a,b end; self >> {|x|}’
-e:1: syntax error, unexpected ‘|’, expecting ‘}’
def self.>>(*a,&b) p a,b end; self >> {|x|}
^
When you use the dot notation then the expression is a normal method
invocation just with an unusual method name. So all the normal method
invocation syntax applies and in that case {} is interpreted as block -
no matter what.
When you use the operator syntax (i.e. no dot) Ruby tries to parse the
right hand side as an expression, which could only be a Hash in this
case since a block is not an expression. You need an expression on the
right hand side because >> is a binary operator.
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.
And what is {}? It’s both a valid Hash and block. And actually Ruby
does parse accordingly:
robert@fussel ~
$ ruby -ce ‘a >> do |x| end’
-e:1: syntax error, unexpected kDO
a >> do |x| end
^
robert@fussel ~
$ ruby -ce ‘a >> {|x| }’
-e:1: syntax error, unexpected ‘|’, expecting ‘}’
a >> {|x| }
^
robert@fussel ~
$ ruby -ce ‘a >> {}’
Syntax OK
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.
I would not consider it an improvement since I don’t see a point in
passing a block to an operator. I don’t see need for improvement here.
Kind regards
robert