~michaelforrest/use-case-mapper/trunk

« back to all changes in this revision

Viewing changes to vendor/rails/activesupport/lib/active_support/core_ext/class/inheritable_attributes.rb

  • Committer: Richard Lee (Canonical)
  • Date: 2010-10-15 15:17:58 UTC
  • mfrom: (190.1.3 use-case-mapper)
  • Revision ID: richard.lee@canonical.com-20101015151758-wcvmfxrexsongf9d
Merge

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Retain for backward compatibility.  Methods are now included in Class.
2
 
module ClassInheritableAttributes # :nodoc:
3
 
end
4
 
 
5
 
# Allows attributes to be shared within an inheritance hierarchy, but where each descendant gets a copy of
6
 
# their parents' attributes, instead of just a pointer to the same. This means that the child can add elements
7
 
# to, for example, an array without those additions being shared with either their parent, siblings, or
8
 
# children, which is unlike the regular class-level attributes that are shared across the entire hierarchy.
9
 
class Class # :nodoc:
10
 
  def class_inheritable_reader(*syms)
11
 
    syms.each do |sym|
12
 
      next if sym.is_a?(Hash)
13
 
      class_eval <<-EOS
14
 
        def self.#{sym}                        # def self.before_add_for_comments
15
 
          read_inheritable_attribute(:#{sym})  #   read_inheritable_attribute(:before_add_for_comments)
16
 
        end                                    # end
17
 
                                               #
18
 
        def #{sym}                             # def before_add_for_comments
19
 
          self.class.#{sym}                    #   self.class.before_add_for_comments
20
 
        end                                    # end
21
 
      EOS
22
 
    end
23
 
  end
24
 
 
25
 
  def class_inheritable_writer(*syms)
26
 
    options = syms.extract_options!
27
 
    syms.each do |sym|
28
 
      class_eval <<-EOS
29
 
        def self.#{sym}=(obj)                          # def self.color=(obj)
30
 
          write_inheritable_attribute(:#{sym}, obj)    #   write_inheritable_attribute(:color, obj)
31
 
        end                                            # end
32
 
                                                       #
33
 
        #{"                                            #
34
 
        def #{sym}=(obj)                               # def color=(obj)
35
 
          self.class.#{sym} = obj                      #   self.class.color = obj
36
 
        end                                            # end
37
 
        " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
38
 
      EOS
39
 
    end
40
 
  end
41
 
 
42
 
  def class_inheritable_array_writer(*syms)
43
 
    options = syms.extract_options!
44
 
    syms.each do |sym|
45
 
      class_eval <<-EOS
46
 
        def self.#{sym}=(obj)                          # def self.levels=(obj)
47
 
          write_inheritable_array(:#{sym}, obj)        #   write_inheritable_array(:levels, obj)
48
 
        end                                            # end
49
 
                                                       #
50
 
        #{"                                            #
51
 
        def #{sym}=(obj)                               # def levels=(obj)
52
 
          self.class.#{sym} = obj                      #   self.class.levels = obj
53
 
        end                                            # end
54
 
        " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
55
 
      EOS
56
 
    end
57
 
  end
58
 
 
59
 
  def class_inheritable_hash_writer(*syms)
60
 
    options = syms.extract_options!
61
 
    syms.each do |sym|
62
 
      class_eval <<-EOS
63
 
        def self.#{sym}=(obj)                          # def self.nicknames=(obj)
64
 
          write_inheritable_hash(:#{sym}, obj)         #   write_inheritable_hash(:nicknames, obj)
65
 
        end                                            # end
66
 
                                                       #
67
 
        #{"                                            #
68
 
        def #{sym}=(obj)                               # def nicknames=(obj)
69
 
          self.class.#{sym} = obj                      #   self.class.nicknames = obj
70
 
        end                                            # end
71
 
        " unless options[:instance_writer] == false }  # # the writer above is generated unless options[:instance_writer] == false
72
 
      EOS
73
 
    end
74
 
  end
75
 
 
76
 
  def class_inheritable_accessor(*syms)
77
 
    class_inheritable_reader(*syms)
78
 
    class_inheritable_writer(*syms)
79
 
  end
80
 
 
81
 
  def class_inheritable_array(*syms)
82
 
    class_inheritable_reader(*syms)
83
 
    class_inheritable_array_writer(*syms)
84
 
  end
85
 
 
86
 
  def class_inheritable_hash(*syms)
87
 
    class_inheritable_reader(*syms)
88
 
    class_inheritable_hash_writer(*syms)
89
 
  end
90
 
 
91
 
  def inheritable_attributes
92
 
    @inheritable_attributes ||= EMPTY_INHERITABLE_ATTRIBUTES
93
 
  end
94
 
 
95
 
  def write_inheritable_attribute(key, value)
96
 
    if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
97
 
      @inheritable_attributes = {}
98
 
    end
99
 
    inheritable_attributes[key] = value
100
 
  end
101
 
 
102
 
  def write_inheritable_array(key, elements)
103
 
    write_inheritable_attribute(key, []) if read_inheritable_attribute(key).nil?
104
 
    write_inheritable_attribute(key, read_inheritable_attribute(key) + elements)
105
 
  end
106
 
 
107
 
  def write_inheritable_hash(key, hash)
108
 
    write_inheritable_attribute(key, {}) if read_inheritable_attribute(key).nil?
109
 
    write_inheritable_attribute(key, read_inheritable_attribute(key).merge(hash))
110
 
  end
111
 
 
112
 
  def read_inheritable_attribute(key)
113
 
    inheritable_attributes[key]
114
 
  end
115
 
 
116
 
  def reset_inheritable_attributes
117
 
    @inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
118
 
  end
119
 
 
120
 
  private
121
 
    # Prevent this constant from being created multiple times
122
 
    EMPTY_INHERITABLE_ATTRIBUTES = {}.freeze unless const_defined?(:EMPTY_INHERITABLE_ATTRIBUTES)
123
 
 
124
 
    def inherited_with_inheritable_attributes(child)
125
 
      inherited_without_inheritable_attributes(child) if respond_to?(:inherited_without_inheritable_attributes)
126
 
 
127
 
      if inheritable_attributes.equal?(EMPTY_INHERITABLE_ATTRIBUTES)
128
 
        new_inheritable_attributes = EMPTY_INHERITABLE_ATTRIBUTES
129
 
      else
130
 
        new_inheritable_attributes = inheritable_attributes.inject({}) do |memo, (key, value)|
131
 
          memo.update(key => value.duplicable? ? value.dup : value)
132
 
        end
133
 
      end
134
 
 
135
 
      child.instance_variable_set('@inheritable_attributes', new_inheritable_attributes)
136
 
    end
137
 
 
138
 
    alias inherited_without_inheritable_attributes inherited
139
 
    alias inherited inherited_with_inheritable_attributes
140
 
end