aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorDavid Heinemeier Hansson <david@loudthinking.com>2012-10-31 17:04:08 +0100
committerDavid Heinemeier Hansson <david@loudthinking.com>2012-10-31 17:04:08 +0100
commitd3494903719682abc0948bef290af0d3d7b5a440 (patch)
treee43e1b4a37d54d58a0a4373916179e478ca1765a /activerecord
parent750a30b19fb0de92d9ae48c4141d60bf8a1cb0e7 (diff)
downloadrails-d3494903719682abc0948bef290af0d3d7b5a440.tar.gz
rails-d3494903719682abc0948bef290af0d3d7b5a440.tar.bz2
rails-d3494903719682abc0948bef290af0d3d7b5a440.zip
Revert "Don't allocate new strings in compiled attribute methods"
This reverts commit f1765019ce9b6292f2264b4601dad5daaffe3a89.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb39
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb20
2 files changed, 20 insertions, 39 deletions
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index 07c8859496..90701938e5 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -32,36 +32,21 @@ module ActiveRecord
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
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index cd33494cc3..fa9097db1f 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -9,19 +9,15 @@ module ActiveRecord
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