Class: Class

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

Overview

Allows attributes to be shared within an inheritance hierarchy, but where 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, which is unlike the regular class-level attributes that are shared across the entire hierarchy.

Constant Summary collapse

EMPTY_INHERITABLE_ATTRIBUTES =

Prevent this constant from being created multiple times

{}.freeze

Instance Method Summary collapse

Instance Method Details

#cattr_accessor(*syms) ⇒ Object



46
47
48
49
# File 'lib/core_ext/class.rb', line 46

def cattr_accessor(*syms)
  cattr_reader(*syms)
  cattr_writer(*syms)
end

#cattr_reader(*syms) ⇒ Object

:nodoc:



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/core_ext/class.rb', line 6

def cattr_reader(*syms)
  syms.flatten.each do |sym|
    next if sym.is_a?(Hash)
    class_eval(<<-EOS, __FILE__, __LINE__)
      unless defined? @@#{sym}
        @@#{sym} = nil
      end

      def self.#{sym}
        @@#{sym}
      end

      def #{sym}
        @@#{sym}
      end
    EOS
  end
end

#cattr_writer(*syms) ⇒ Object



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/core_ext/class.rb', line 25

def cattr_writer(*syms)
  options = syms.last.is_a?(Hash) ? syms.pop : {}
  syms.flatten.each do |sym|
    class_eval(<<-EOS, __FILE__, __LINE__)
      unless defined? @@#{sym}
        @@#{sym} = nil
      end

      def self.#{sym}=(obj)
        @@#{sym} = obj
      end

      #{"
      def #{sym}=(obj)
        @@#{sym} = obj
      end
      " unless options[:instance_writer] == false }
    EOS
  end
end

#class_inheritable_accessor(*syms) ⇒ Object



116
117
118
119
# File 'lib/core_ext/class.rb', line 116

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

#class_inheritable_array(*syms) ⇒ Object



121
122
123
124
# File 'lib/core_ext/class.rb', line 121

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

#class_inheritable_array_writer(*syms) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/core_ext/class.rb', line 82

def class_inheritable_array_writer(*syms)
  options = syms.last.is_a?(Hash) ? syms.pop : {}
  syms.each do |sym|
    class_eval <<-EOS
      def self.#{sym}=(obj)
        write_inheritable_array(:#{sym}, obj)
      end

      #{"
      def #{sym}=(obj)
        self.class.#{sym} = obj
      end
      " unless options[:instance_writer] == false }
    EOS
  end
end

#class_inheritable_hash(*syms) ⇒ Object



126
127
128
129
# File 'lib/core_ext/class.rb', line 126

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

#class_inheritable_hash_writer(*syms) ⇒ Object



99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/core_ext/class.rb', line 99

def class_inheritable_hash_writer(*syms)
  options = syms.last.is_a?(Hash) ? syms.pop : {}
  syms.each do |sym|
    class_eval <<-EOS
      def self.#{sym}=(obj)
        write_inheritable_hash(:#{sym}, obj)
      end

      #{"
      def #{sym}=(obj)
        self.class.#{sym} = obj
      end
      " unless options[:instance_writer] == false }
    EOS
  end
end

#class_inheritable_reader(*syms) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/core_ext/class.rb', line 50

def class_inheritable_reader(*syms)
  syms.each do |sym|
    next if sym.is_a?(Hash)
    class_eval <<-EOS
      def self.#{sym}
        read_inheritable_attribute(:#{sym})
      end

      def #{sym}
        self.class.#{sym}
      end
    EOS
  end
end

#class_inheritable_writer(*syms) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/core_ext/class.rb', line 65

def class_inheritable_writer(*syms)
  options = syms.last.is_a?(Hash) ? syms.pop : {}
  syms.each do |sym|
    class_eval <<-EOS
      def self.#{sym}=(obj)
        write_inheritable_attribute(:#{sym}, obj)
      end

      #{"
      def #{sym}=(obj)
        self.class.#{sym} = obj
      end
      " unless options[:instance_writer] == false }
    EOS
  end
end

#inheritable_attributesObject



131
132
133
# File 'lib/core_ext/class.rb', line 131

def inheritable_attributes
  @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
end

#read_inheritable_attribute(key) ⇒ Object



152
153
154
# File 'lib/core_ext/class.rb', line 152

def read_inheritable_attribute(key)
  inheritable_attributes[key]
end

#reset_inheritable_attributesObject



156
157
158
# File 'lib/core_ext/class.rb', line 156

def reset_inheritable_attributes
  @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
end

#write_inheritable_array(key, elements) ⇒ Object



142
143
144
145
# File 'lib/core_ext/class.rb', line 142

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



135
136
137
138
139
140
# File 'lib/core_ext/class.rb', line 135

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



147
148
149
150
# File 'lib/core_ext/class.rb', line 147

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