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.
This seems to work:
#! /usr/bin/env ruby
module CommonMethods
def shout_my_constant
puts self::Const.upcase
end
end
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
NonInstantiableClass.shout_my_constant
HTH
Its probably worth noting that you don't need to include modules into a metaclass.
class NonInstantiableClass
Const = "hello, world!"
class << self
include CommonMethods
end
end
Ruby has the extend
keyword that effectively adds the modules interface to a class, e.g.
class NonInstantiableClass
Const = "hello, world!"
extend CommonMethods
end
You still need to ensure you're referencing the right constant using self::Const
or const_get
, but extend <module>
is the better way to add those methods to the class.
The problem is, if you just write Const
it is evaluated on Module creation time. You have to use Module#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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With