When foo
is an undefined variable, attempting to access it raises a NameError
:
foo
#=> NameError: undefined local variable or method `foo'
a = foo
#=> NameError: undefined local variable or method `foo'
Why doesn't foo = foo
raise a NameError
?
foo = foo
#=> nil
Yesterday, it took me hours to track down this line as the bug in a program...
capture = capture.to_i
What I had intended to do was convert capture_str
to an Integer
. What I had done instead was introduce a nil
by saying capture = capture
, and then turning that nil into a 0
. So I was doing this...
capture = capture.to_i
#=> 0
But I had been incorrectly assuming that a variable NameError
would have been thrown, like this...
capture = capture_str.to_i
#=> NameError: undefined local variable or method `capture_str'
Ruby has this weird feature that it hoists variables when they're declared:
This means that when the parser sees x=1, it will actually declare the variable, by assigning it to nil and let the interpreter then figure out if the x = 1 line will ever get executed.
source
So when you write
a = a.to_i
it first declare a = nil
then calls to_i
on it and the assigns:
a = nil
a = a.to_i
EDIT:
It also works like that in other cases, e.g. with if
:
pry> b
NameError: undefined local variable or method `b' for main:Object
from (pry):30:in `__pry__'
pry> b if b.nil?
NameError: undefined local variable or method `b' for main:Object
from (pry):31:in `__pry__'
pry> b = 1 if b.nil?
#=> 1
pry> b
#=> 1
and (example from the linked blogpost):
if false
x = 1
end
puts x.class
# NilClass
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With