Simon Ninon Simon Ninon - 2 months ago 10
Ruby Question

ruby: share class variable inheritance

In my Rails application, I got a concern which is included within a base class. The base class is then inherited.

The included module defines a class variable for which I'd like to have the same value whether or not I'm in the base class or child class.

The code looks like something similar:

module M

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

module ClassMethods

attr_accessor :lol

def toto
@lol ||= {}
end

def toto=(val)
@lol = val
end

end

end


class A
include M
end

class B < A
end

puts A::toto
puts B::toto
puts A::toto = 12
puts B::toto


I'm actually using concerns, but the behavior is the same.

This code prints

{}
{}
12
{}


while I'd like

{}
{}
12
12


Is there any wa to achieve that?
I've tried different combination of attr_accessor / cattr_accessor, but nothing worked.

Answer

Try the following:

module M
  def self.included(base)
    base.extend ClassMethods
    base.instance_eval do
      cattr_accessor :toto, instance_writer: false, instance_reader: false do 
        {}
      end          
    end  
  end

  module ClassMethods
    # class methods 
  end
end


class A
  include M
end

class B < A
end

puts A.toto
puts B.toto
puts A.toto = 12
puts B.toto

# {}
# {}
# 12
# 12
Comments