Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Revert "Don't allocate new strings in compiled attribute methods"

This reverts commit f176501.
  • Loading branch information...
commit d3494903719682abc0948bef290af0d3d7b5a440 1 parent 750a30b
@dhh dhh authored
View
39 activerecord/lib/active_record/attribute_methods/read.rb
@@ -32,36 +32,21 @@ def cache_attribute?(attr_name)
protected
- # We want to generate the methods via module_eval rather than
- # define_method, because define_method is slower on dispatch and
- # uses more memory (because it creates a closure).
+ # We want to generate the methods via module_eval rather than define_method,
+ # because define_method is slower on dispatch and uses more memory (because it
+ # creates a closure).
#
- # But sometimes the database might return columns with
- # characters that are not allowed in normal method names (like
- # 'my_column(omg)'. So to work around this we first define with
- # the __temp__ identifier, and then use alias method to rename
- # it to what we want.
- #
- # We are also defining a constant to hold the frozen string of
- # the attribute name. Using a constant means that we do not have
- # to allocate an object on each call to the attribute method.
- # Making it frozen means that it doesn't get duped when used to
- # key the @attributes_cache in read_attribute.
- def define_method_attribute(name)
- safe_name = name.unpack('h*').first
+ # But sometimes the database might return columns with characters that are not
+ # allowed in normal method names (like 'my_column(omg)'. So to work around this
+ # we first define with the __temp__ identifier, and then use alias method to
+ # rename it to what we want.
+ def define_method_attribute(attr_name)
generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
- module AttrNames
- unless defined? ATTR_#{safe_name}
- ATTR_#{safe_name} = #{name.inspect}.freeze
- end
+ def __temp__
+ read_attribute('#{attr_name}') { |n| missing_attribute(n, caller) }
end
-
- def __temp__#{safe_name}
- read_attribute(AttrNames::ATTR_#{safe_name}) { |n| missing_attribute(n, caller) }
- end
-
- alias_method #{name.inspect}, :__temp__#{safe_name}
- undef_method :__temp__#{safe_name}
+ alias_method '#{attr_name}', :__temp__
+ undef_method :__temp__
STR
end
View
20 activerecord/lib/active_record/attribute_methods/write.rb
@@ -9,19 +9,15 @@ module Write
module ClassMethods
protected
-
- # See define_method_attribute in read.rb for an explanation of
- # this code.
- def define_method_attribute=(name)
- safe_name = name.unpack('h*').first
- generated_attribute_methods.module_eval <<-STR, __FILE__, __LINE__ + 1
- def __temp__#{safe_name}=(value)
- write_attribute(AttrNames::ATTR_#{safe_name}, value)
+ def define_method_attribute=(attr_name)
+ if attr_name =~ ActiveModel::AttributeMethods::NAME_COMPILABLE_REGEXP
+ generated_attribute_methods.module_eval("def #{attr_name}=(new_value); write_attribute('#{attr_name}', new_value); end", __FILE__, __LINE__)
+ else
+ generated_attribute_methods.send(:define_method, "#{attr_name}=") do |new_value|
+ write_attribute(attr_name, new_value)
+ end
end
- alias_method #{(name + '=').inspect}, :__temp__#{safe_name}=
- undef_method :__temp__#{safe_name}=
- STR
- end
+ end
end
# Updates the attribute identified by <tt>attr_name</tt> with the

1 comment on commit d349490

@dhh
Owner

@jonleighton I reverted this commit until we have a chance to fix it fully as it's a complete blocker at the moment.

Please sign in to comment.
Something went wrong with that request. Please try again.