Search code examples
rubyruby-2.5

Removing constant results in constant still being available


Check that Object constant is defined

Module.const_defined?('Object')
#=> true

Remove the constant

Object.send(:remove_const, 'Object')
#=> Object

Check, that Object constant is removed

Module.const_defined?('Object')
#=> false

Now, how do the following examples return the Object constant if it is removed? :)

String.superclass
#=> Object
new_object = String.superclass.new
#=> #<Object:0x00007fdc18382858>
new_object.class
#=> Object

Solution

  • Now, how do the following examples return the Object constant if it is removed?

    They don't. They can't. Constants aren't objects in Ruby, therefore, they cannot possibly return the ::Object constant.

    They can, however, return an object which responds to inspect with the string 'Object'. An object, which happens to be the same object which used to be referenced by the now-removed ::Object constant.

    Removing the constant removes the constant. Nothing more. In particular, it does not delete the object that is referenced by the constant. IFF that constant was the only reference to that object, THEN that object will now be eligible for garbage collection. But that is not the case here: the ::Object constant is not the only reference to the Object class, since every subclass of the Object class has a reference to the Object class in its superclass pointer and every instance of the Object class has a reference to the Object class in its class pointer. Plus, internal data structures of the execution engine may or may not have references to the Object class.

    Therefore, the Object class will pretty much never get garbage collected, and you will always have some reference to it, through which you can access it, e.g. ''.class.superclass will give you access to the Object class regardless of whether or not the ::Object constant still exists.

    In short: you are confusing the constant ::Object with the object that is referenced by this constant. This is a common beginner mistake. However, the distinction between the name of a thing and the thing itself is fundamental in almost all programming languages.