Because the assignment of x happens and it’s not lost…
puts "x before all: "
puts “#{x.inspect}” rescue puts “x is nil”
puts "x before the if: "
puts “#{x.inspect}” if(x = 2) rescue puts “x is still nil”
puts “but x after the if: #{x.inspect}”
If you run your snippet with debugging on (-d) you will see a warning
about an unused variable…
For example:
Your example doesn’t show such a warning.
if() when used as a modifier has its own context… its scope.
So the assignment is never seen outside of the if and ‘bar’ it’s undefined.
I believe this is incorrect and sows confusion. In reality, the reason puts a if a = 0.zero? fails if a hasn’t been defined is because the parser
scans strictly from left to right looking for assignments. When it finds
an
assignment, it considers the left side of that assignment to be a valid
variable from there to the end of the scope. It doesn’t backtrack into
the
portion of the line before a modifier-if, so puts a is unable to
resolve
the variable a.
[1] pry(main)> puts a if a = 0.zero?
NameError: undefined local variable or method a' for main:Object from (pry):1:inpry’
[2] pry(main)> a
=> true
[3] pry(main)>
If anything that is defined gets into this inner scope and anything that
is defined (or modified) inside the inner scope gets out, then this is
not really a scope…
Another example, which doesn’t create a noise like local variable in my
first post.
(arup~>~)$ pry --simple-prompt
puts meth if eval(‘def meth;12;end’).nil?
12
=> nil
if() when used as a modifier has its own context… its scope.
So the assignment is never seen outside of the if and ‘bar’ it’s
undefined.
But ‘a’ gets defined after the error. Does it mean that it first gets
defined in the inner scope and passed to the outer scope?
[1] pry(main)> puts a if a = 0.zero?
NameError: undefined local variable or method a' for main:Object from (pry):1:inpry’
[2] pry(main)> a
=> true
[3] pry(main)>
If anything that is defined gets into this inner scope and anything that
is defined (or modified) inside the inner scope gets out, then this is
not really a scope…