Inherit class-level instance variables in Ruby?

inheritance, instance-variables, oop, ruby, scope

Solution

Use a mixin:

module ClassLevelInheritableAttributes
  def self.included(base)
    base.extend(ClassMethods)    
  end

  module ClassMethods
    def inheritable_attributes(*args)
      @inheritable_attributes ||= [:inheritable_attributes]
      @inheritable_attributes += args
      args.each do |arg|
        class_eval %(
          class << self; attr_accessor :#{arg} end
        )
      end
      @inheritable_attributes
    end

    def inherited(subclass)
      @inheritable_attributes.each do |inheritable_attribute|
        instance_var = "@#{inheritable_attribute}"
        subclass.instance_variable_set(instance_var, instance_variable_get(instance_var))
      end
    end
  end
end

Including this module in a class, gives it two class methods: inheritable_attributes and inherited. The inherited class method works the same as the self.included method in the module shown. Whenever a class that includes this module gets subclassed, it sets a class level instance variable for each of declared class level inheritable instance variables (@inheritable_attributes).

Problem

I want a child class to inherit a class-level instance variable from its parent, but I can't seem to figure it out. Basically I'm looking for functionality like this: ``` class Alpha class_instance_inheritable_accessor :foo # @foo = [1, 2, 3] end class Beta < Alpha @foo << 4 def self.bar @foo end end class Delta < Alpha @foo << 5 def self.bar @foo end end class Gamma < Beta @foo << 'a' def self.bar @foo end end ``` And then I want this to output like this: ``` > Alpha.bar # [1, 2, 3] > Beta.bar # [1, 2, 3, 4] > Delta.bar # [1, 2, 3, 5] > Gamma.bar # [1, 2, 3, 4, 'a'] ``` Obviously, this code doesn't work. Basically I want to define a default value for a class-level instance variables in the parent class, which its subclasses inherit. A change in a subclass will be the default value then for a sub-subclass. I want this all to happen without a change in one class's value affecting its parent or siblings. Class_inheritable_accessor gives exactly the behavior I want... but for a class variable. I feel like I might be asking too much. Any ideas?

Original source

Related problems