Given the following method:
def some_method
:value
end
The following statements work as I would expect:
some_method || :other
# => :value
x = some_method || :other
# => :value
But the behaviour of the following statement perplexes me:
some_method = some_method || :other
# => :other
It creates a local variable called some_method
as expected, and subsequent calls to some_method
return the value of that local variable. But why does it assign :other
rather than :value
?
I understand that it's probably not a smart thing to do, and can see how it might be ambiguous, but I thought the right-hand-side of the assignment should be evaluated prior to the assignment being considered...
I've tested this in Ruby 1.8.7 and Ruby 1.9.2 with开发者_如何学JAVA identical results.
Cheers!
Paul
There have been similar questions, but not exactly the same. Jörg's answer here seems to hit the point, I'm quoting the relevant part:
At this point,
foo
is defined, even though the line will never get executed. The fact that the line never gets executed is completely irrelevant, because the interpreter has nothing to do with this anyway: local variables are defined by the parser, and the parser obviously sees this line.
So, in your case, regardless of the fact that a method with the same name already exists, the parser sees some_method
assignment and it automatically "tags" the identifier to be local variable. So, when interpreter starts evaluating the right-hand-side of the assignment, it already considers some_method
to be local variable, not a method. Its value is unassigned (nil
by default), so the result of ||
will be :other
.
A simple answer is: your last statement is the same as
some_var = some_var || :other
because when you have a local variable in scope with the same name as a method, the interpreter gives the local variable precedence.
精彩评论