aboutsummaryrefslogtreecommitdiffstats
path: root/activesupport
diff options
context:
space:
mode:
authorthedarkone <thedarkone2@gmail.com>2010-09-24 18:01:47 +0200
committerthedarkone <thedarkone2@gmail.com>2010-09-27 17:45:58 +0200
commit320382ccd359397f2c83f8c0c622b296dcfb472b (patch)
tree63b05e867cdad652f2be9e5a5d195e5078324a57 /activesupport
parent5a518487fe66b11b81e21dc6c31d036057a410ed (diff)
downloadrails-320382ccd359397f2c83f8c0c622b296dcfb472b.tar.gz
rails-320382ccd359397f2c83f8c0c622b296dcfb472b.tar.bz2
rails-320382ccd359397f2c83f8c0c622b296dcfb472b.zip
Creating singleton class for every object whenever the instance-level accessor is used quite is expensive.
Diffstat (limited to 'activesupport')
-rw-r--r--activesupport/lib/active_support/core_ext/class/attribute.rb22
1 files changed, 21 insertions, 1 deletions
diff --git a/activesupport/lib/active_support/core_ext/class/attribute.rb b/activesupport/lib/active_support/core_ext/class/attribute.rb
index 688cba03db..511f26963e 100644
--- a/activesupport/lib/active_support/core_ext/class/attribute.rb
+++ b/activesupport/lib/active_support/core_ext/class/attribute.rb
@@ -72,11 +72,20 @@ class Class
remove_possible_method(:#{name})
define_method(:#{name}) { val }
end
+
+ if singleton_class?
+ class_eval do
+ remove_possible_method(:#{name})
+ def #{name}
+ defined?(@#{name}) ? @#{name} : singleton_class.#{name}
+ end
+ end
+ end
val
end
def #{name}
- defined?(@#{name}) ? @#{name} : singleton_class.#{name}
+ defined?(@#{name}) ? @#{name} : self.class.#{name}
end
def #{name}?
@@ -87,4 +96,15 @@ class Class
attr_writer name if instance_writer
end
end
+
+ private
+ def singleton_class?
+ # in case somebody is crazy enough to overwrite allocate
+ allocate = Class.instance_method(:allocate)
+ # object.class always points to a real (non-singleton) class
+ allocate.bind(self).call.class != self
+ rescue TypeError
+ # MRI/YARV/JRuby all disallow creating new instances of a singleton class
+ true
+ end
end