@@ -117,6 +117,9 @@ def attribute(*names, default: NOT_SET)
117
117
raise ArgumentError , "Restricted attribute names: #{ invalid_attribute_names . join ( ", " ) } "
118
118
end
119
119
120
+ Delegation . generate ( singleton_class , names , to : :instance , nilable : false , signature : "" )
121
+ Delegation . generate ( singleton_class , names . map { |n | "#{ n } =" } , to : :instance , nilable : false , signature : "value" )
122
+
120
123
ActiveSupport ::CodeGenerator . batch ( generated_attribute_methods , __FILE__ , __LINE__ ) do |owner |
121
124
names . each do |name |
122
125
owner . define_cached_method ( name , namespace : :current_attributes ) do |batch |
@@ -134,9 +137,6 @@ def attribute(*names, default: NOT_SET)
134
137
end
135
138
end
136
139
137
- Delegation . generate ( singleton_class , names , to : :instance , nilable : false , signature : "" )
138
- Delegation . generate ( singleton_class , names . map { |n | "#{ n } =" } , to : :instance , nilable : false , signature : "value" )
139
-
140
140
self . defaults = defaults . merge ( names . index_with { default } )
141
141
end
142
142
@@ -185,9 +185,16 @@ def respond_to_missing?(name, _)
185
185
186
186
def method_added ( name )
187
187
super
188
+
189
+ # We try to generate instance delegators early to not rely on method_missing.
188
190
return if name == :initialize
191
+
192
+ # If the added method isn't public, we don't delegate it.
189
193
return unless public_method_defined? ( name )
194
+
195
+ # If we already have a class method by that name, we don't override it.
190
196
return if singleton_class . method_defined? ( name ) || singleton_class . private_method_defined? ( name )
197
+
191
198
Delegation . generate ( singleton_class , [ name ] , to : :instance , as : self , nilable : false )
192
199
end
193
200
end
0 commit comments