38
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?

0

1 Answer 1

90

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 true
    a = 1
  end
  puts a
end

test
# Will print 1

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.

Sign up to request clarification or add additional context in comments.

3 Comments

Up-click for for the first two sentences, though I don't believe the rest added anything pertinent to the question.
nice explanation, and the whole answer was absolutely relevant to the question, since the OP asked why the variable isn't nil.
It's probably worth to mention that the comparison with JavaScript is true for the var keyword but not for const and let which have become the recommended ways to define variables there.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.