Reputation: 9886
Given the following code:
a = true # let's assign `a` a value
# and let's test if calling `b`, an unassigned variable, throws an error
begin
puts "The value of b is: #{b.inspect}"
rescue NameError => e
puts "Caught an error: #{e}"
end
a || b = true # the assignment should never be executed because `a` is `true`
puts "The value of b is: #{b.inspect}" # will calling `b` still raise an error?
We get the following result:
Caught an error: undefined local variable or method `b' for main:Object
The value of b is: nil
Even though we expected calling b
to raise an error the second time, we see that b
is now, in fact, nil
.
Why is that? Why does b
get assigned nil
? Since the ||
never reached the assignment, I would expect b
to remain undefined. How can it be defined, but not assigned a value?
Upvotes: 3
Views: 182
Reputation: 3662
Some of the docs explain how variables are created; the explanation as I understand it is that's just how the parser works:
The local variable is created when the parser encounters the assignment, not when the assignment occurs:
a = 0 if false # does not assign to a
p local_variables # prints [:a]
p a # prints nil
You can see other examples of this:
b = true if false # b is nil
"test" || c = true # c is nil
And others it doesn't get assigned:
puts d if false # d generates a NameError
Upvotes: 5