This afternoon my pair and I spent quite a while on a subtle bug. The culprit? Variable hoisting.
Take this file:
class Test def self.hoist require 'pry'; binding.pry; bar = 1 end end Test.hoist
When we hit the PRY debugger, what will the value of
bar be? I would have thought it would raise
bar has seemingly not yet been defined.
$ ruby test.rb From: /test.rb @ line 4 Test.hoist: 2: def self.hoist 3: require 'pry'; binding.pry; => 4: bar = 1 5: end  pry(Test)> bar => nil
When Ruby parses a file, it ‘hoists’ each variable to the top of its scope, declaring and setting it to
nil, even if that variable is never assigned by our code. So variables inside an
if false conditional get hoisted and set to
nil, as described in this blog post.
This is can be a real gotcha.
h/t Jack ChristensenTweet