In order to share data between class and class instance, ActiveSupport has magnificent method class_attribute. For example
require 'active_support/core_ext/class/attribute.rb'
# Step 1: declare a class record and implement class_attribute :fields.
# We can use it to declare attr_accessor
class Record
class_attribute :fields
self.fields = [:id]
def self.attribute(new_field_name)
self.fields = fields | [new_field_name]
instance_eval do
attr_accessor new_field_name
end
end
end
# Step 2: Declare class Topic with two attributes
class Topic < Record
attribute :title
attribute :body
end
# Step 3: Declare another class user with other two attributes
# And one more class with addition attribute
class User < Record
attribute :first_name
attribute :last_name
end
# Step 4: Let's check.
# Each class has it own attributes and data is shared between class and instances
puts Topic.fields
# [:id, :title, :body]
puts Topic.new.fields
# [:id, :title, :body]
puts User.fields
# [:id, :first_name, :last_name]
puts User.new.fields
# [:id, :first_name, :last_name]
I write a little ruby script and don't want to have an additional dependency on ActiveSupport. Also, I can't use class variables (variables with "@@") because changing value on subclasses will impact the parent class.
As on option - I can copy and paste class_attribute source code to my Ruby-script, but I'm curious to find a solution in pure Ruby