31
def foo
  #bar = nil
  if true
    bar = 1
  else
    bar = 2
  end
  bar #<-- shouldn't this refer to nil since the bar from the if statement is removed from the stack?
end

puts foo # prints "1"

I always thought you had to make a temporary variable and define it as nil or an initial value so that variables defined inside an if/else statement would persist outside the scope of the if/else statement and not disappear off the stack?? Why does it print 1 and not nil?

bigpotato
  • 24,574
  • 50
  • 160
  • 313

1 Answers1

81

Variables are local to a function, class or module defintion, a proc, a block.

In ruby if is an expression and the branches don't have their own scope.

Also note that whenever the parser sees a variable assignment, it will create a variable in the scope, even if that code path isn't executed:

def test
  if false
    a = 1
  end
  puts a
end

test
# ok, it's nil.

It's bit similar to JavaScript, though it doesn't hoist the variable to the top of the scope:

def test
  puts a
  a = 1
end

test
# NameError: undefined local variable or method `a' for ...

So even if what you were saying were true, it still wouldn't be nil.

Community
  • 1
  • 1
Karoly Horvath
  • 91,854
  • 11
  • 113
  • 173