undefining constants on class autoload?

This probably sounds crazy but has it even been considered to either have a way to register constants for an autoloaded class so they will be undefined before reload, or maybe even just a class method to do:

def_const(:SOME_CONSTANT, value)

that would:

def def_const(constant, value) remove_const(constant) if const_defined?(constant) constant = value end

Some say to put constants where they aren’t autoloaded (like in initializers) and other even suggest using methods, but that defeats the purpose of using constants. So does the method above, but it is more in line with what Rails autoloading promises.

Seems like avoiding the problem makes some consider just using magic numbers in code which is like stepping back into time.

The problem with this system is that it's not normal Ruby, and if someone doesn't use it, and uses Ruby, it all breaks.

This probably sounds crazy but has it even been considered to either have a way to register constants for an autoloaded class so they will be undefined before reload, or maybe even just a class method to do:

def_const(:SOME_CONSTANT, value)

that would:

def def_const(constant, value) remove_const(constant) if const_defined?(constant) constant = value end

Some say to put constants where they aren’t autoloaded (like in initializers) and other even suggest using methods, but that defeats the purpose of using constants. So does the method above, but it is more in line with what Rails autoloading promises.

Seems like avoiding the problem makes some consider just using magic numbers in code which is like stepping back into time.

If they’re constants, that belong to the class, then make them constants inside the class:

class MyModel < ActiveRecord::Model

SOME_CONSTANT = 42

end

That will reload correctly.

$ irb 1.9.3p194 :001 > class Class 1.9.3p194 :002?> def def_const(constant, value) 1.9.3p194 :003?> remove_const(constant) if const_defined?(constant) 1.9.3p194 :004?> const_set(constant, value) 1.9.3p194 :005?> end 1.9.3p194 :006?> end => nil 1.9.3p194 :007 > class Something 1.9.3p194 :008?> def_const(:HI, 1) 1.9.3p194 :009?> end => 1 1.9.3p194 :010 > class Something 1.9.3p194 :011?> def_const(:HI, 1) 1.9.3p194 :012?> end => 1 1.9.3p194 :013 > Something::HI => 1

Like that.

This is one of the things that got me concerned: Do we need constants? - avdi.codes

It’s neat, but seems wrong (no offense to those using that technique).