aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2013-07-03 11:37:26 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2013-07-03 11:37:41 -0700
commitefb6c16b40fe8f43341e4511fd811e58030a8afd (patch)
tree7312e39030335ecd584c43b9dd1ad37d03fb5bfe /activerecord
parentaa7b0ad428cdf38210f7654a4b48a154523dd235 (diff)
downloadrails-efb6c16b40fe8f43341e4511fd811e58030a8afd.tar.gz
rails-efb6c16b40fe8f43341e4511fd811e58030a8afd.tar.bz2
rails-efb6c16b40fe8f43341e4511fd811e58030a8afd.zip
refactor the method cache objects to have a superclass
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/attribute_methods.rb25
-rw-r--r--activerecord/lib/active_record/attribute_methods/read.rb34
-rw-r--r--activerecord/lib/active_record/attribute_methods/write.rb33
3 files changed, 41 insertions, 51 deletions
diff --git a/activerecord/lib/active_record/attribute_methods.rb b/activerecord/lib/active_record/attribute_methods.rb
index 2fd2ea896b..c07fd67216 100644
--- a/activerecord/lib/active_record/attribute_methods.rb
+++ b/activerecord/lib/active_record/attribute_methods.rb
@@ -28,6 +28,31 @@ module ActiveRecord
end
}
+ class AttributeMethodCache
+ include Mutex_m
+
+ def initialize
+ super
+ @module = Module.new
+ @method_cache = {}
+ end
+
+ def [](name)
+ synchronize do
+ @method_cache.fetch(name) {
+ safe_name = name.unpack('h*').first
+ temp_method = "__temp__#{safe_name}"
+ ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
+ @module.module_eval method_body(temp_method, safe_name), __FILE__, __LINE__
+ @method_cache[name] = @module.instance_method temp_method
+ }
+ end
+ end
+
+ private
+ def method_body; raise NotImplementedError; end
+ end
+
module ClassMethods
def inherited(child_class) #:nodoc:
child_class.initialize_generated_modules
diff --git a/activerecord/lib/active_record/attribute_methods/read.rb b/activerecord/lib/active_record/attribute_methods/read.rb
index d43f4b55e8..c7d861a957 100644
--- a/activerecord/lib/active_record/attribute_methods/read.rb
+++ b/activerecord/lib/active_record/attribute_methods/read.rb
@@ -1,15 +1,8 @@
module ActiveRecord
module AttributeMethods
module Read
- ReaderMethodCache = Class.new {
- include Mutex_m
-
- def initialize
- super
- @module = Module.new
- @method_cache = {}
- end
-
+ ReaderMethodCache = Class.new(AttributeMethodCache) {
+ private
# We want to generate the methods via module_eval rather than
# define_method, because define_method is slower on dispatch.
# Evaluating many similar methods may use more memory as the instruction
@@ -28,24 +21,13 @@ module ActiveRecord
# 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 [](name)
- synchronize do
- @method_cache.fetch(name) {
- safe_name = name.unpack('h*').first
- temp_method = "__temp__#{safe_name}"
-
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
-
- @module.module_eval <<-STR, __FILE__, __LINE__ + 1
- def #{temp_method}
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
- read_attribute(name) { |n| missing_attribute(n, caller) }
- end
- STR
-
- @method_cache[name] = @module.instance_method temp_method
- }
+ def method_body(method_name, const_name)
+ <<-EOMETHOD
+ def #{method_name}
+ name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name}
+ read_attribute(name) { |n| missing_attribute(n, caller) }
end
+ EOMETHOD
end
}.new
diff --git a/activerecord/lib/active_record/attribute_methods/write.rb b/activerecord/lib/active_record/attribute_methods/write.rb
index 813a85d2f7..f865f0b2c8 100644
--- a/activerecord/lib/active_record/attribute_methods/write.rb
+++ b/activerecord/lib/active_record/attribute_methods/write.rb
@@ -1,33 +1,16 @@
module ActiveRecord
module AttributeMethods
module Write
- WriterMethodCache = Class.new {
- include Mutex_m
+ WriterMethodCache = Class.new(AttributeMethodCache) {
+ private
- def initialize
- super
- @module = Module.new
- @method_cache = {}
- end
-
- def [](name)
- synchronize do
- @method_cache.fetch(name) {
- safe_name = name.unpack('h*').first
- temp_method = "__temp__#{safe_name}="
-
- ActiveRecord::AttributeMethods::AttrNames.set_name_cache safe_name, name
-
- @module.module_eval <<-STR, __FILE__, __LINE__ + 1
- def #{temp_method}(value)
- name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{safe_name}
- write_attribute(name, value)
- end
- STR
-
- @method_cache[name] = @module.instance_method temp_method
- }
+ def method_body(method_name, const_name)
+ <<-EOMETHOD
+ def #{method_name}(value)
+ name = ::ActiveRecord::AttributeMethods::AttrNames::ATTR_#{const_name}
+ write_attribute(name, value)
end
+ EOMETHOD
end
}.new