Class: Class

Inherits:
Object
  • Object
show all
Defined in:
lib/class_inheritable_attributes.rb

Overview

Allows attributes to be shared within an inheritance hierarchy. Each descendant gets a copy of their parents’ attributes, instead of just a pointer to the same. This means that the child can add elements to, for example, an array without those additions being shared with either their parent, siblings, or children. This is unlike the regular class-level attributes that are shared across the entire hierarchy.

The copies of inheritable parent attributes are added to subclasses when they are created, via the inherited hook.

class Person
  class_inheritable_accessor :hair_colors
end

Person.hair_colors = [:brown, :black, :blonde, :red]
Person.hair_colors     # => [:brown, :black, :blonde, :red]
Person.new.hair_colors # => [:brown, :black, :blonde, :red]

To opt out of the instance writer method, pass :instance_writer => false. To opt out of the instance reader method, pass :instance_reader => false.

class Person
  class_inheritable_accessor :hair_colors :instance_writer => false, :instance_reader => false
end

Person.new.hair_colors = [:brown]  # => NoMethodError
Person.new.hair_colors             # => NoMethodError

Instance Method Summary collapse

Instance Method Details

#class_inheritable_accessor(*syms) ⇒ Object



105
106
107
108
# File 'lib/class_inheritable_attributes.rb', line 105

def class_inheritable_accessor(*syms)
  class_inheritable_reader(*syms)
  class_inheritable_writer(*syms)
end

#class_inheritable_array(*syms) ⇒ Object



110
111
112
113
# File 'lib/class_inheritable_attributes.rb', line 110

def class_inheritable_array(*syms)
  class_inheritable_reader(*syms)
  class_inheritable_array_writer(*syms)
end

#class_inheritable_array_writer(*syms) ⇒ Object



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/class_inheritable_attributes.rb', line 71

def class_inheritable_array_writer(*syms)
  options = syms.extract_options!
  syms.each do |sym|
    class_eval(<<-EOS, __FILE__, __LINE__ + 1)
      def self.#{sym}=(obj)                          # def self.levels=(obj)
        write_inheritable_array(:#{sym}, obj)        #   write_inheritable_array(:levels, obj)
      end                                            # end
                                                     #
      #{"                                            #
      def #{sym}=(obj)                               # def levels=(obj)
        self.class.#{sym} = obj                      #   self.class.levels = obj
      end                                            # end
      " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
    EOS
  end
end

#class_inheritable_hash(*syms) ⇒ Object



115
116
117
118
# File 'lib/class_inheritable_attributes.rb', line 115

def class_inheritable_hash(*syms)
  class_inheritable_reader(*syms)
  class_inheritable_hash_writer(*syms)
end

#class_inheritable_hash_writer(*syms) ⇒ Object



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/class_inheritable_attributes.rb', line 88

def class_inheritable_hash_writer(*syms)
  options = syms.extract_options!
  syms.each do |sym|
    class_eval(<<-EOS, __FILE__, __LINE__ + 1)
      def self.#{sym}=(obj)                          # def self.nicknames=(obj)
        write_inheritable_hash(:#{sym}, obj)         #   write_inheritable_hash(:nicknames, obj)
      end                                            # end
                                                     #
      #{"                                            #
      def #{sym}=(obj)                               # def nicknames=(obj)
        self.class.#{sym} = obj                      #   self.class.nicknames = obj
      end                                            # end
      " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
    EOS
  end
end

#class_inheritable_reader(*syms) ⇒ Object

:nodoc:



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/class_inheritable_attributes.rb', line 36

def class_inheritable_reader(*syms)
  options = syms.extract_options!
  syms.each do |sym|
    next if sym.is_a?(Hash)
    class_eval(<<-EOS, __FILE__, __LINE__ + 1)
      def self.#{sym}                                # def self.after_add
        read_inheritable_attribute(:#{sym})          #   read_inheritable_attribute(:after_add)
      end                                            # end
                                                     #
      #{"                                            #
      def #{sym}                                     # def after_add
        self.class.#{sym}                            #   self.class.after_add
      end                                            # end
      " unless options[:instance_reader] == false }  # # the reader above is generated unless options[:instance_reader] == false
    EOS
  end
end

#class_inheritable_writer(*syms) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/class_inheritable_attributes.rb', line 54

def class_inheritable_writer(*syms)
  options = syms.extract_options!
  syms.each do |sym|
    class_eval(<<-EOS, __FILE__, __LINE__ + 1)
      def self.#{sym}=(obj)                          # def self.color=(obj)
        write_inheritable_attribute(:#{sym}, obj)    #   write_inheritable_attribute(:color, obj)
      end                                            # end
                                                     #
      #{"                                            #
      def #{sym}=(obj)                               # def color=(obj)
        self.class.#{sym} = obj                      #   self.class.color = obj
      end                                            # end
      " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
    EOS
  end
end

#inheritable_attributesObject



120
121
122
# File 'lib/class_inheritable_attributes.rb', line 120

def inheritable_attributes
  @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
end

#read_inheritable_attribute(key) ⇒ Object



141
142
143
# File 'lib/class_inheritable_attributes.rb', line 141

def read_inheritable_attribute(key)
  inheritable_attributes[key]
end

#reset_inheritable_attributesObject



145
146
147
# File 'lib/class_inheritable_attributes.rb', line 145

def reset_inheritable_attributes
  @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
end

#write_inheritable_array(key, elements) ⇒ Object



131
132
133
134
# File 'lib/class_inheritable_attributes.rb', line 131

def write_inheritable_array(key, elements)
  write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
  write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
end

#write_inheritable_attribute(key, value) ⇒ Object



124
125
126
127
128
129
# File 'lib/class_inheritable_attributes.rb', line 124

def write_inheritable_attribute(key, value)
  if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
    @inheritable_attributes = {}
  end
  inheritable_attributes[key] = value
end

#write_inheritable_hash(key, hash) ⇒ Object



136
137
138
139
# File 'lib/class_inheritable_attributes.rb', line 136

def write_inheritable_hash(key, hash)
  write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
  write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
end