Have a parent class's method access the subclass's constants Have a parent class's method access the subclass's constants ruby ruby

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


one way to do it without class instance variables:

class Animal def make_noise   print self.class::NOISE endendclass Dog < Animal  NOISE = "bark"endd = Dog.newd.make_noise # prints bark


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 method make_noise.
  • instances of class Animal may call the method make_noise.
  • class Dogdefines the constant NOISE with its value.
  • instances of Dog and the class Dog itself may use the constant NOISE.

What is not possible:

  • Instances of Animal or the class Animal itself have access to constants of the class Dog.

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:

  1. Define an abstract method in class Animal which defines that make_noise should be defined. See the answer https://stackoverflow.com/a/6792499/41540.
  2. Define in your concrete classes the method again, but now with the reference to the constant.