Reputation: 1319
I've read a few things, including this and this, but I think the below example is different than what they're talking about. One person actually raises a similar example in the discussion but it's ignored.
So, run in irb (ignore the warnings about assignment in the conditional):
(puts x) if (x = 0) # NameError: undefined local variable or method `x'...
x # => 0
(puts x) if (x = 0) # "0", => nil
but the second time there's no error.
Does this make any sense, even in a "once you understand what the parser is really doing and that this just some optimization it all becomes clear" kind of way? Because to me, it seems pretty undesirable.
To be clear, the above conditional should be equivalent (right?) to
if newvar=0
puts newvar
end
which does not raise an error.
Update: There have been even more posts on this topic since this question was asked. For example,
http://seejohncode.com/2012/07/31/ruby-gotcha-single-line-conditionals/.
Upvotes: 2
Views: 138
Reputation: 26979
I think the difference in this case is whether the variable exists when it parses the line. In the case of:
if x=0
puts x
end
the variable x is defined before it parses the line that uses x.
In other words, the error message is a parse time error, not a runtime error.
Upvotes: 1
Reputation: 3924
First, check that you mean x=0
in the conditional clause.
Second, puts x if x = 0
is not equivalent to:
if x = 0
puts x
end
In your case, x is not declared yet for puts x
so it cannot see it.
Upvotes: 0
Reputation: 23225
Oddly enough, this works fine in Rubinius:
Welcome to IRB. You are using rubinius 1.2.4dev (1.8.7 7ae451a1 yyyy-mm-dd JI)
>> (puts x) if (x = 0) #=> nil
0
I'm inclined to say it's a weird parsing bug in MRI.
Upvotes: 1
Reputation: 1418
I think in this you are assigning 0 to x.
(puts x) if (x = 0)
i think it should be
(puts x) if (x == 0)
Upvotes: 0