active-fedora 9.10.0.pre1 → 9.10.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -0
- data/lib/active_fedora.rb +4 -0
- data/lib/active_fedora/associations/collection_association.rb +7 -7
- data/lib/active_fedora/attribute_assignment.rb +55 -0
- data/lib/active_fedora/attribute_methods.rb +149 -47
- data/lib/active_fedora/attribute_methods/read.rb +29 -44
- data/lib/active_fedora/attribute_methods/write.rb +16 -19
- data/lib/active_fedora/attributes.rb +5 -17
- data/lib/active_fedora/base.rb +2 -0
- data/lib/active_fedora/callbacks.rb +9 -9
- data/lib/active_fedora/common.rb +67 -0
- data/lib/active_fedora/core.rb +9 -22
- data/lib/active_fedora/errors.rb +29 -0
- data/lib/active_fedora/file.rb +5 -57
- data/lib/active_fedora/file_persistence.rb +27 -0
- data/lib/active_fedora/identifiable.rb +0 -5
- data/lib/active_fedora/indexing.rb +2 -2
- data/lib/active_fedora/inheritance.rb +34 -0
- data/lib/active_fedora/persistence.rb +22 -4
- data/lib/active_fedora/scoping.rb +80 -2
- data/lib/active_fedora/scoping/default.rb +6 -2
- data/lib/active_fedora/scoping/named.rb +141 -1
- data/lib/active_fedora/version.rb +1 -1
- data/spec/integration/collection_association_spec.rb +34 -3
- data/spec/integration/file_spec.rb +1 -1
- data/spec/integration/persistence_spec.rb +1 -1
- data/spec/unit/attributes_spec.rb +13 -7
- data/spec/unit/file_spec.rb +2 -2
- data/spec/unit/validations_spec.rb +1 -1
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9fa729bb22950bf6f1a5a8910eef83e17d699b6
|
4
|
+
data.tar.gz: 2230ceaf9cf100c0737997c5235c0a87364ec2df
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: df06b4f7448346189c3ca49029200205eaf671a84854035fba131dc60d84f0954aaf79df54e29746118cac1074ca2241e7b5bc7e291f89b120e44340b034d250
|
7
|
+
data.tar.gz: 60a819b84ffd5f68bdb80436648621738e2b77b68e629265be3d3257efa566969d33c040660a561445c39a60d38742865afd0dd6b6681ef0aeb7bfc8cd08d961
|
data/.rubocop.yml
CHANGED
@@ -43,6 +43,9 @@ Metrics/CyclomaticComplexity:
|
|
43
43
|
- 'lib/active_fedora/file_configurator.rb'
|
44
44
|
- 'lib/active_fedora/file.rb'
|
45
45
|
- 'lib/active_fedora/datastreams/nokogiri_datastreams.rb'
|
46
|
+
- 'lib/active_fedora/attribute_methods.rb'
|
47
|
+
- 'lib/active_fedora/scoping/named.rb'
|
48
|
+
- 'lib/active_fedora/inheritance.rb'
|
46
49
|
|
47
50
|
Metrics/PerceivedComplexity:
|
48
51
|
Exclude:
|
@@ -57,6 +60,9 @@ Metrics/PerceivedComplexity:
|
|
57
60
|
- 'lib/active_fedora/associations/builder/indirectly_contains.rb'
|
58
61
|
- 'lib/active_fedora/associations/builder/directly_contains_one.rb'
|
59
62
|
- 'lib/active_fedora/associations/collection_association.rb'
|
63
|
+
- 'lib/active_fedora/attribute_methods.rb'
|
64
|
+
- 'lib/active_fedora/scoping/named.rb'
|
65
|
+
- 'lib/active_fedora/inheritance.rb'
|
60
66
|
|
61
67
|
Metrics/ModuleLength:
|
62
68
|
Exclude:
|
@@ -103,6 +109,7 @@ Style/AccessorMethodName:
|
|
103
109
|
|
104
110
|
Style/PredicateName:
|
105
111
|
Exclude:
|
112
|
+
- 'lib/active_fedora/attribute_methods.rb'
|
106
113
|
- 'lib/active_fedora/relation/finder_methods.rb'
|
107
114
|
- 'lib/active_fedora/versionable.rb'
|
108
115
|
- 'lib/active_fedora/reflection.rb'
|
data/lib/active_fedora.rb
CHANGED
@@ -40,6 +40,7 @@ module ActiveFedora #:nodoc:
|
|
40
40
|
autoload :AssociationRelation
|
41
41
|
autoload :Associations
|
42
42
|
autoload :AttachedFiles
|
43
|
+
autoload :AttributeAssignment
|
43
44
|
autoload :AttributeMethods
|
44
45
|
autoload :Attributes
|
45
46
|
autoload :AutosaveAssociation
|
@@ -50,6 +51,7 @@ module ActiveFedora #:nodoc:
|
|
50
51
|
autoload :Checksum
|
51
52
|
autoload :CleanConnection
|
52
53
|
autoload :Config
|
54
|
+
autoload :Common
|
53
55
|
autoload :Core
|
54
56
|
autoload_under 'containers' do
|
55
57
|
autoload :Container
|
@@ -71,6 +73,7 @@ module ActiveFedora #:nodoc:
|
|
71
73
|
autoload :File
|
72
74
|
autoload :FileConfigurator
|
73
75
|
autoload :FilePathBuilder
|
76
|
+
autoload :FilePersistence
|
74
77
|
autoload :FileRelation
|
75
78
|
autoload :FilesHash
|
76
79
|
autoload :FixityService
|
@@ -79,6 +82,7 @@ module ActiveFedora #:nodoc:
|
|
79
82
|
autoload :Indexing
|
80
83
|
autoload :IndexingService
|
81
84
|
autoload :InheritableAccessors
|
85
|
+
autoload :Inheritance
|
82
86
|
autoload :InboundRelationConnection
|
83
87
|
autoload :LdpCache
|
84
88
|
autoload :LdpResource
|
@@ -72,10 +72,10 @@ module ActiveFedora
|
|
72
72
|
# This method is abstract in the sense that it relies on
|
73
73
|
# +count_records+, which is a method descendants have to provide.
|
74
74
|
def size
|
75
|
-
if
|
76
|
-
|
77
|
-
elsif !loaded? &&
|
78
|
-
unsaved_records =
|
75
|
+
if !find_target? || loaded?
|
76
|
+
target.size
|
77
|
+
elsif !loaded? && target.is_a?(Array)
|
78
|
+
unsaved_records = target.select(&:new_record?)
|
79
79
|
unsaved_records.size + count_records
|
80
80
|
else
|
81
81
|
count_records
|
@@ -212,7 +212,7 @@ module ActiveFedora
|
|
212
212
|
if attrs.is_a?(Array)
|
213
213
|
attrs.collect { |attr| create(attr) }
|
214
214
|
else
|
215
|
-
|
215
|
+
_create_record(attrs) do |record|
|
216
216
|
yield(record) if block_given?
|
217
217
|
record.save
|
218
218
|
end
|
@@ -220,7 +220,7 @@ module ActiveFedora
|
|
220
220
|
end
|
221
221
|
|
222
222
|
def create!(attrs = {})
|
223
|
-
|
223
|
+
_create_record(attrs) do |record|
|
224
224
|
yield(record) if block_given?
|
225
225
|
record.save!
|
226
226
|
end
|
@@ -340,7 +340,7 @@ module ActiveFedora
|
|
340
340
|
end
|
341
341
|
end
|
342
342
|
|
343
|
-
def
|
343
|
+
def _create_record(attributes, raise = false)
|
344
344
|
attributes.update(@reflection.options[:conditions]) if @reflection.options[:conditions].is_a?(Hash)
|
345
345
|
ensure_owner_is_not_new
|
346
346
|
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'active_support/core_ext/hash/keys'
|
2
|
+
|
3
|
+
module ActiveFedora
|
4
|
+
module AttributeAssignment
|
5
|
+
include ActiveModel::ForbiddenAttributesProtection
|
6
|
+
|
7
|
+
# Alias for assign_attributes.
|
8
|
+
def attributes=(attributes)
|
9
|
+
assign_attributes(attributes)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Allows you to set all the attributes by passing in a hash of attributes with
|
13
|
+
# keys matching the attribute names.
|
14
|
+
#
|
15
|
+
# If the passed hash responds to <tt>permitted?</tt> method and the return value
|
16
|
+
# of this method is +false+ an <tt>ActiveModel::ForbiddenAttributesError</tt>
|
17
|
+
# exception is raised.
|
18
|
+
#
|
19
|
+
# class Cat
|
20
|
+
# include ActiveModel::AttributeAssignment
|
21
|
+
# attr_accessor :name, :status
|
22
|
+
# end
|
23
|
+
#
|
24
|
+
# cat = Cat.new
|
25
|
+
# cat.assign_attributes(name: "Gorby", status: "yawning")
|
26
|
+
# cat.name # => 'Gorby'
|
27
|
+
# cat.status => 'yawning'
|
28
|
+
# cat.assign_attributes(status: "sleeping")
|
29
|
+
# cat.name # => 'Gorby'
|
30
|
+
# cat.status => 'sleeping'
|
31
|
+
def assign_attributes(new_attributes)
|
32
|
+
unless new_attributes.respond_to?(:stringify_keys)
|
33
|
+
raise ArgumentError, "When assigning attributes, you must pass a hash as an argument."
|
34
|
+
end
|
35
|
+
return if new_attributes.nil? || new_attributes.empty?
|
36
|
+
|
37
|
+
attributes = new_attributes.stringify_keys
|
38
|
+
_assign_attributes(sanitize_for_mass_assignment(attributes))
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def _assign_attributes(attributes)
|
44
|
+
attributes.each do |k, v|
|
45
|
+
_assign_attribute(k, v)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def _assign_attribute(k, v)
|
50
|
+
raise UnknownAttributeError.new(self, k) unless respond_to?("#{k}=")
|
51
|
+
|
52
|
+
public_send("#{k}=", v)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -13,26 +13,97 @@ module ActiveFedora
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
BLACKLISTED_CLASS_METHODS = %w(private public protected allocate new name parent superclass).freeze
|
17
|
+
|
18
|
+
class GeneratedAttributeMethods < Module; end # :nodoc:
|
19
|
+
|
20
|
+
module ClassMethods
|
21
|
+
def inherited(child_class) #:nodoc:
|
22
|
+
child_class.initialize_generated_modules
|
23
|
+
super
|
24
|
+
end
|
25
|
+
|
26
|
+
def initialize_generated_modules # :nodoc:
|
27
|
+
@generated_attribute_methods = GeneratedAttributeMethods.new { extend Mutex_m }
|
28
|
+
@attribute_methods_generated = false
|
29
|
+
include @generated_attribute_methods
|
30
|
+
|
31
|
+
super
|
32
|
+
end
|
33
|
+
|
34
|
+
# Raises an ActiveRecord::DangerousAttributeError exception when an
|
35
|
+
# \Active \Record method is defined in the model, otherwise +false+.
|
36
|
+
#
|
37
|
+
# class Person < ActiveRecord::Base
|
38
|
+
# def save
|
39
|
+
# 'already defined by Active Record'
|
40
|
+
# end
|
41
|
+
# end
|
42
|
+
#
|
43
|
+
# Person.instance_method_already_implemented?(:save)
|
44
|
+
# # => ActiveRecord::DangerousAttributeError: save is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name.
|
45
|
+
#
|
46
|
+
# Person.instance_method_already_implemented?(:name)
|
47
|
+
# # => false
|
48
|
+
def instance_method_already_implemented?(method_name)
|
49
|
+
if dangerous_attribute_method?(method_name)
|
50
|
+
raise DangerousAttributeError, "#{method_name} is defined by Active Record. Check to make sure that you don't have an attribute or method with the same name."
|
51
|
+
end
|
52
|
+
|
53
|
+
if superclass == Base
|
54
|
+
super
|
55
|
+
else
|
56
|
+
# If ThisClass < ... < SomeSuperClass < ... < Base and SomeSuperClass
|
57
|
+
# defines its own attribute method, then we don't want to overwrite that.
|
58
|
+
defined = method_defined_within?(method_name, superclass, Base) &&
|
59
|
+
!superclass.instance_method(method_name).owner.is_a?(GeneratedAttributeMethods)
|
60
|
+
defined || super
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# A method name is 'dangerous' if it is already (re)defined by Active Fedora, but
|
65
|
+
# not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
|
66
|
+
def dangerous_attribute_method?(name) # :nodoc:
|
67
|
+
method_defined_within?(name, Base)
|
68
|
+
end
|
69
|
+
|
70
|
+
def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
|
71
|
+
if klass.method_defined?(name) || klass.private_method_defined?(name)
|
72
|
+
if superklass.method_defined?(name) || superklass.private_method_defined?(name)
|
73
|
+
klass.instance_method(name).owner != superklass.instance_method(name).owner
|
74
|
+
else
|
75
|
+
true
|
76
|
+
end
|
77
|
+
else
|
78
|
+
false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
# A class method is 'dangerous' if it is already (re)defined by Active Record, but
|
83
|
+
# not by any ancestors. (So 'puts' is not dangerous but 'new' is.)
|
84
|
+
def dangerous_class_method?(method_name)
|
85
|
+
BLACKLISTED_CLASS_METHODS.include?(method_name.to_s) || class_method_defined_within?(method_name, Base)
|
20
86
|
end
|
21
87
|
|
22
|
-
def
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
88
|
+
def class_method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
|
89
|
+
if klass.respond_to?(name, true)
|
90
|
+
if superklass.respond_to?(name, true)
|
91
|
+
klass.method(name).owner != superklass.method(name).owner
|
92
|
+
else
|
93
|
+
true
|
94
|
+
end
|
95
|
+
else
|
96
|
+
false
|
29
97
|
end
|
30
98
|
end
|
31
99
|
|
32
100
|
private
|
33
101
|
|
34
|
-
|
35
|
-
|
102
|
+
# @param name [Symbol] name of the attribute to generate
|
103
|
+
def generate_method(name)
|
104
|
+
generated_attribute_methods.synchronize do
|
105
|
+
define_attribute_methods name
|
106
|
+
end
|
36
107
|
end
|
37
108
|
end
|
38
109
|
|
@@ -43,6 +114,19 @@ module ActiveFedora
|
|
43
114
|
include Dirty
|
44
115
|
end
|
45
116
|
|
117
|
+
# Returns +true+ if the given attribute is in the attributes hash, otherwise +false+.
|
118
|
+
#
|
119
|
+
# class Person < ActiveRecord::Base
|
120
|
+
# end
|
121
|
+
#
|
122
|
+
# person = Person.new
|
123
|
+
# person.has_attribute?(:name) # => true
|
124
|
+
# person.has_attribute?('age') # => true
|
125
|
+
# person.has_attribute?(:nothing) # => false
|
126
|
+
def has_attribute?(attr_name)
|
127
|
+
attribute_names.include?(attr_name.to_s)
|
128
|
+
end
|
129
|
+
|
46
130
|
# Returns an array of names for the attributes available on this object.
|
47
131
|
#
|
48
132
|
# class Person < ActiveFedora::Base
|
@@ -69,6 +153,58 @@ module ActiveFedora
|
|
69
153
|
end
|
70
154
|
end
|
71
155
|
|
156
|
+
# Returns an <tt>#inspect</tt>-like string for the value of the
|
157
|
+
# attribute +attr_name+. String attributes are truncated up to 50
|
158
|
+
# characters, Date and Time attributes are returned in the
|
159
|
+
# <tt>:db</tt> format, Array attributes are truncated up to 10 values.
|
160
|
+
# Other attributes return the value of <tt>#inspect</tt> without
|
161
|
+
# modification.
|
162
|
+
#
|
163
|
+
# person = Person.create!(name: 'David Heinemeier Hansson ' * 3)
|
164
|
+
#
|
165
|
+
# person.attribute_for_inspect(:name)
|
166
|
+
# # => "\"David Heinemeier Hansson David Heinemeier Hansson ...\""
|
167
|
+
#
|
168
|
+
# person.attribute_for_inspect(:created_at)
|
169
|
+
# # => "\"2012-10-22 00:15:07\""
|
170
|
+
#
|
171
|
+
# person.attribute_for_inspect(:tag_ids)
|
172
|
+
# # => "[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ...]"
|
173
|
+
def attribute_for_inspect(attr_name)
|
174
|
+
value = self[attr_name]
|
175
|
+
|
176
|
+
if value.is_a?(String) && value.length > 50
|
177
|
+
"#{value[0, 50]}...".inspect
|
178
|
+
elsif value.is_a?(Date) || value.is_a?(Time)
|
179
|
+
%("#{value.to_s(:db)}")
|
180
|
+
elsif value.is_a?(Array) && value.size > 10
|
181
|
+
inspected = value.first(10).inspect
|
182
|
+
%(#{inspected[0...-1]}, ...])
|
183
|
+
else
|
184
|
+
value.inspect
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Returns +true+ if the specified +attribute+ has been set by the user or by a
|
189
|
+
# database load and is neither +nil+ nor <tt>empty?</tt> (the latter only applies
|
190
|
+
# to objects that respond to <tt>empty?</tt>, most notably Strings). Otherwise, +false+.
|
191
|
+
# Note that it always returns +true+ with boolean attributes.
|
192
|
+
#
|
193
|
+
# class Task < ActiveRecord::Base
|
194
|
+
# end
|
195
|
+
#
|
196
|
+
# task = Task.new(title: '', is_done: false)
|
197
|
+
# task.attribute_present?(:title) # => false
|
198
|
+
# task.attribute_present?(:is_done) # => true
|
199
|
+
# task.title = 'Buy milk'
|
200
|
+
# task.is_done = true
|
201
|
+
# task.attribute_present?(:title) # => true
|
202
|
+
# task.attribute_present?(:is_done) # => true
|
203
|
+
def attribute_present?(attribute)
|
204
|
+
value = self[attribute]
|
205
|
+
!value.nil? && !(value.respond_to?(:empty?) && value.empty?)
|
206
|
+
end
|
207
|
+
|
72
208
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after it has been typecast (for example,
|
73
209
|
# "2004-12-12" in a date column is cast to a date object, like Date.new(2004, 12, 12)). It raises
|
74
210
|
# <tt>ActiveModel::MissingAttributeError</tt> if the identified attribute is missing.
|
@@ -103,39 +239,5 @@ module ActiveFedora
|
|
103
239
|
def []=(attr_name, value)
|
104
240
|
write_attribute(attr_name, value)
|
105
241
|
end
|
106
|
-
|
107
|
-
module ClassMethods
|
108
|
-
def initialize_generated_modules # :nodoc:
|
109
|
-
@generated_attribute_methods = Module.new { extend Mutex_m }
|
110
|
-
include @generated_attribute_methods
|
111
|
-
end
|
112
|
-
|
113
|
-
# A method name is 'dangerous' if it is already (re)defined by Active Fedora, but
|
114
|
-
# not by any ancestors. (So 'puts' is not dangerous but 'save' is.)
|
115
|
-
def dangerous_attribute_method?(name) # :nodoc:
|
116
|
-
method_defined_within?(name, Base)
|
117
|
-
end
|
118
|
-
|
119
|
-
def method_defined_within?(name, klass, superklass = klass.superclass) # :nodoc:
|
120
|
-
if klass.method_defined?(name) || klass.private_method_defined?(name)
|
121
|
-
if superklass.method_defined?(name) || superklass.private_method_defined?(name)
|
122
|
-
klass.instance_method(name).owner != superklass.instance_method(name).owner
|
123
|
-
else
|
124
|
-
true
|
125
|
-
end
|
126
|
-
else
|
127
|
-
false
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
private
|
132
|
-
|
133
|
-
# @param name [Symbol] name of the attribute to generate
|
134
|
-
def generate_method(name)
|
135
|
-
generated_attribute_methods.synchronize do
|
136
|
-
define_attribute_methods name
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end
|
140
242
|
end
|
141
243
|
end
|
@@ -1,61 +1,46 @@
|
|
1
1
|
module ActiveFedora
|
2
2
|
module AttributeMethods
|
3
3
|
module Read
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
def method_body(method_name, const_name)
|
26
|
-
<<-EOMETHOD
|
27
|
-
def #{method_name}
|
28
|
-
name = ::ActiveFedora::AttributeMethods::AttrNames::ATTR_#{const_name}
|
29
|
-
read_attribute(name) { |n| missing_attribute(n, caller) }
|
4
|
+
module ClassMethods
|
5
|
+
protected
|
6
|
+
|
7
|
+
def define_method_attribute(name)
|
8
|
+
name = name.to_s
|
9
|
+
safe_name = name.unpack('h*'.freeze).first
|
10
|
+
temp_method = "__temp__#{safe_name}"
|
11
|
+
|
12
|
+
ActiveFedora::AttributeMethods::AttrNames.set_name_cache safe_name, name
|
13
|
+
|
14
|
+
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
|
15
|
+
def #{temp_method}
|
16
|
+
name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
|
17
|
+
_read_attribute(name) { |n| missing_attribute(n, caller) }
|
18
|
+
end
|
19
|
+
STR
|
20
|
+
|
21
|
+
generated_attribute_methods.module_eval do
|
22
|
+
alias_method name, temp_method
|
23
|
+
undef_method temp_method
|
24
|
+
end
|
30
25
|
end
|
31
|
-
|
32
|
-
end
|
33
|
-
end.new
|
26
|
+
end
|
34
27
|
|
35
28
|
extend ActiveSupport::Concern
|
36
29
|
|
37
30
|
# Returns the value of the attribute identified by <tt>attr_name</tt> after
|
38
31
|
# it has been typecast (for example, "2004-12-12" in a date column is cast
|
39
32
|
# to a date object, like Date.new(2004, 12, 12)).
|
40
|
-
def read_attribute(attr_name)
|
33
|
+
def read_attribute(attr_name, &block)
|
41
34
|
name = attr_name.to_s
|
42
|
-
|
35
|
+
_read_attribute(name, &block)
|
43
36
|
end
|
44
37
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
read_attribute(attribute_name)
|
49
|
-
end
|
38
|
+
def _read_attribute(attr_name) # :nodoc:
|
39
|
+
@attributes.fetch(attr_name.to_s) { |n| yield n if block_given? }
|
40
|
+
end
|
50
41
|
|
51
|
-
|
52
|
-
|
53
|
-
method = ReaderMethodCache[name.to_s]
|
54
|
-
generated_attribute_methods.module_eval do
|
55
|
-
define_method name, method
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
42
|
+
alias attribute _read_attribute
|
43
|
+
private :attribute
|
59
44
|
end
|
60
45
|
end
|
61
46
|
end
|