Search code examples
rubyscopeiteratorblock

Ruby lexical scope inside iterator block


In Ruby (v2.5.0)...

[1,2,3].map do |i|
  if i.eql?(3)
    a = 123
  end
  defined?(a)
end
=> ["local-variable", "local-variable", "local-variable"]

Can someone please explain to me how a can be a local-variable (equal to nil) in the first and second iteration, if it's not set until the third iteration?

Thanks in advance!


Solution

  • I will answer quoting a book by A.Black: Well Grounded Rubyist, Chapter 6, p. 158. (second edition 2014):

    When the Ruby parser sees the sequence identifier, equal-sign, and value, as in this expression,

    a = 123

    it allocates space for a local variable a. The creation of the variable - not the assignment of a value to it, but the internal creation of a variable - always takes place as a result of this kind of expression, event if the code isn't executed.