4

I can undefine Bar (How to undefine class in Ruby?), but how to undefine Foo::Bar ?

irb(main):266:0> Object.send :remove_const, :ActiveRecord::Base
TypeError: :ActiveRecord is not a class/module

irb(main):267:0> Object.send :remove_const, :"ActiveRecord::Base"
NameError: `ActiveRecord::Base' is not allowed as a constant name

irb(main):269:0> module ActiveRecord; Object.send :remove_const, :Base; end
NameError: constant Object::Base not defined
Community
  • 1
  • 1
zuba
  • 1,488
  • 1
  • 17
  • 50

1 Answers1

11

Constants are defined in their respective parent module, with top-level constants being defined on the Object class.

Thus, ActiveRecord::Base is a constant(Base) which is defined on the ActiveRecord module. Now, in order to remove this constant, you have to call the remove_const method on the ActiveRecord module:

ActiveRecord.send(:remove_const, :Base)

Alternatively, you could also traverse the path directly from Object, i.e.

Object.const_get(:ActiveRecord).send(:remove_const, :Base)
Holger Just
  • 52,918
  • 14
  • 115
  • 123
  • Ok, I see that it works for Foo::Bar, but it doesn't for ActiveRecord::Base `irb(main):001:0> ActiveRecord.send(:remove_const, :Base) NameError: uninitialized constant ActiveRecord::Core::ClassMethods::Base` or `irb(main):002:0> Object.const_get(:ActiveRecord).send(:const_delete, :Base) NoMethodError: undefined method 'const_delete' for ActiveRecord:Module` Is that happens because ActiveRecord undefines :const_delete method? – zuba May 20 '15 at 13:20
  • Well, ActiveRecord is actually a rather complex thing. It includes other modules and heavily uses meta-programming. As such, it can be difficult to manipulate. As for the typo in my answer (the `const_delete`), I just fixed it. – Holger Just May 20 '15 at 13:58