Class: Class

Inherits:
Object
  • Object
show all
Defined in:
lib/core_ext/delegating_attributes.rb,
lib/core_ext/inheritable_attributes.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

#class_inheritable_accessor(*syms) ⇒ Object



72
73
74
75
# File 'lib/core_ext/inheritable_attributes.rb', line 72

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

#class_inheritable_array(*syms) ⇒ Object



77
78
79
80
# File 'lib/core_ext/inheritable_attributes.rb', line 77

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

#class_inheritable_array_writer(*syms) ⇒ Object



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

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)                          # 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



82
83
84
85
# File 'lib/core_ext/inheritable_attributes.rb', line 82

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

#class_inheritable_hash_writer(*syms) ⇒ Object



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

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)                          # 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:



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

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

#class_inheritable_writer(*syms) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/core_ext/inheritable_attributes.rb', line 21

def class_inheritable_writer(*syms)
  options = syms.last.is_a?(::Hash) ? syms.pop : {}
  syms.each do |sym|
    class_eval <<-EOS
      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



87
88
89
# File 'lib/core_ext/inheritable_attributes.rb', line 87

def inheritable_attributes
  @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
end

#read_inheritable_attribute(key) ⇒ Object



108
109
110
# File 'lib/core_ext/inheritable_attributes.rb', line 108

def read_inheritable_attribute(key)
  inheritable_attributes[key]
end

#reset_inheritable_attributesObject



112
113
114
# File 'lib/core_ext/inheritable_attributes.rb', line 112

def reset_inheritable_attributes
  @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
end

#superclass_delegating_accessor(*names) ⇒ Object



71
72
73
74
# File 'lib/core_ext/delegating_attributes.rb', line 71

def superclass_delegating_accessor(*names)
  superclass_delegating_reader(*names)
  superclass_delegating_writer(*names)
end

#superclass_delegating_reader(*names) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/core_ext/delegating_attributes.rb', line 32

def superclass_delegating_reader(*names)
  class_name_to_stop_searching_on = self.superclass.name.blank? ? "Object" : self.superclass.name
  names.each do |name|
    class_eval <<-EOS
    def self.#{name}                                            # def self.only_reader
      if defined?(@#{name})                                     #   if defined?(@only_reader)
        @#{name}                                                #     @only_reader
      elsif superclass < #{class_name_to_stop_searching_on} &&  #   elsif superclass < Object &&
            superclass.respond_to?(:#{name})                    #         superclass.respond_to?(:only_reader)
        superclass.#{name}                                      #     superclass.only_reader
      end                                                       #   end
    end                                                         # end
    def #{name}                                                 # def only_reader
      self.class.#{name}                                        #   self.class.only_reader
    end                                                         # end
    def self.#{name}?                                           # def self.only_reader?
      !!#{name}                                                 #   !!only_reader
    end                                                         # end
    def #{name}?                                                # def only_reader?
      !!#{name}                                                 #   !!only_reader
    end                                                         # end
    EOS
  end
end

#superclass_delegating_writer(*names) ⇒ Object



59
60
61
62
63
64
65
66
67
# File 'lib/core_ext/delegating_attributes.rb', line 59

def superclass_delegating_writer(*names)
  names.each do |name|
    class_eval <<-EOS
      def self.#{name}=(value)  # def self.only_writer=(value)
        @#{name} = value        #   @only_writer = value
      end                       # end
    EOS
  end
end

#write_inheritable_array(key, elements) ⇒ Object



98
99
100
101
# File 'lib/core_ext/inheritable_attributes.rb', line 98

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



91
92
93
94
95
96
# File 'lib/core_ext/inheritable_attributes.rb', line 91

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



103
104
105
106
# File 'lib/core_ext/inheritable_attributes.rb', line 103

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