Have a parent class's method access the subclass's constants
I think that you don't really want a constant; I think that you want an instance variable on the class:
class Animal @noise = "whaargarble" class << self attr_accessor :noise end def make_noise puts self.class.noise endendclass Dog < Animal @noise = "bark"enda = Animal.newd = Dog.newa.make_noise #=> "whaargarble"d.make_noise #=> "bark"Dog.noise = "WOOF"d.make_noise #=> "WOOF"a.make_noise #=> "whaargarble"
However, if you are sure that you want a constant:
class Animal def make_noise puts self.class::NOISE # or self.class.const_get(:NOISE) endend
I think you have the wrong concept here. Classes in Ruby are similar to classes in Java, Smalltalk, C#, ... and all are templates for their instances. So the class defines the structure and the behavior if its instances, and the parts of the structure and behavior of the instances of its subclasses but not vice versae.
So direct access from a superclass to a constant in a subclass is not possible at all, and that is a good thing. See below how to fix it. For your classes defined, the following things are true:
class Animal
defines the methodmake_noise
.- instances of
class Animal
may call the methodmake_noise
. class Dog
defines the constantNOISE
with its value.- instances of
Dog
and the classDog
itself may use the constantNOISE
.
What is not possible:
- Instances of
Animal
or the classAnimal
itself have access to constants of the classDog
.
You may fix that by the following change:
class Animal def make_noise print Dog::NOISE endend
But this is bad style, because now, your superclass (which is an abstraction about Dog
and other animals) knows now something that belongs to Dog
.
A better solution would be:
- Define an abstract method in class
Animal
which defines thatmake_noise
should be defined. See the answer https://stackoverflow.com/a/6792499/41540. - Define in your concrete classes the method again, but now with the reference to the constant.