Changes to constant unloading in Ruby 2.4

We noticed some interesting behavior recently while upgrading to Rails 5.0.1 and Ruby 2.4. Between MRI 2.3x branch and 2.4.0, constant unloading no longer affects variable references to the unloaded class constant:

ref = Object.const_set(“ASD”, Class.new)
=> ASD
2.4.0 :014 > Object.send(:remove_const, “ASD”)
=> ASD
2.4.0 :015 > ref.name
=> “ASD”

In previous versions of Ruby, ref.name would return nil. In fact, in 2.4 the reference doesn’t appear to be unloaded in nearly any sense of the word – I can do ref.new and it will create a new instance of the ASD class, and calling instance.class on it will return ASD. The only change appears to be that directly trying to reference ASD now results in a NameError.

At first I thought this had something to do with threadsafety, but now I’m not so sure; Ruby lets you do all sorts of things that can silently affect behavior in other threads (like redefining methods and classes), so this reasoning would be inconsistent with that design.

Anyways, there are 3,392 commits between 2.3.0 and 2.4.0. Should be fun to track down.

Leave a Reply

Your email address will not be published. Required fields are marked *