active-fedora 9.10.0.pre1 → 9.10.0.pre2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|