I have a class with a constant defined for it. I then have a class method defined that accesses that class constant. This works fine. An example:
#! /usr/bin/env ruby
class NonInstantiableClass
Const = "hello, world!"
class << self
def shout_my_constant
puts Const.upcase
end
end
end
NonInstantiableClass.shout_my_constant
My problem arises in attempting to move this class method out to an external module, like so:
#! /usr/bin/env ruby
module CommonMethods
def shout_my_constant
puts Const.upcase
end
end
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
NonInstantiableClass.shout_my_constant
Ruby interprets the method as requesting a constant from the module, rather than the class:
line 5:in `shout_my_constant': uninitialized constant CommonMethods::Const (NameError)
So, what magic tricks do you fellows have to let the method access the class constant? Many thanks.
The problem is, if you just write
Const
it is evaluated on Module creation time. You have to useModule#const_get
instead like this:const_get(:Const)
. This is evaluated at runtime when the method is executed. So this happens in your class and not in your module.This seems to work:
HTH
Its probably worth noting that you don't need to include modules into a metaclass.
Ruby has the
extend
keyword that effectively adds the modules interface to a class, e.g.You still need to ensure you're referencing the right constant using
self::Const
orconst_get
, butextend <module>
is the better way to add those methods to the class.