From 8d8b573275495648a5bb423198be3575e476cfd1 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 15 Dec 2007 02:12:39 +0000 Subject: [PATCH] Bypass const_missing lookup for toplevel constants. Optimizes for Ruby 1.9 const_defined. git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8396 5ecf4fe2-1ee6-0310-87b1-e25e094e27de --- .../lib/active_support/dependencies.rb | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/activesupport/lib/active_support/dependencies.rb b/activesupport/lib/active_support/dependencies.rb index 823e6040a9..d1ca9f0473 100644 --- a/activesupport/lib/active_support/dependencies.rb +++ b/activesupport/lib/active_support/dependencies.rb @@ -216,7 +216,7 @@ def qualified_name_for(mod, name) end # Load the constant named +const_name+ which is missing from +from_mod+. If - # it is not possible to laod the constant into from_mod, try its parent module + # it is not possible to load the constant into from_mod, try its parent module # using const_missing. def load_missing_constant(from_mod, const_name) log_call from_mod, const_name @@ -236,7 +236,7 @@ def load_missing_constant(from_mod, const_name) unless qualified_const_defined?(from_mod.name) && from_mod.name.constantize.object_id == from_mod.object_id raise ArgumentError, "A copy of #{from_mod} has been removed from the module tree but is still active!" end - + raise ArgumentError, "#{from_mod} is not missing constant #{const_name}!" if from_mod.const_defined?(const_name) qualified_name = qualified_name_for from_mod, const_name @@ -460,21 +460,26 @@ def unloadable(const_desc = self) end class Class - def const_missing(class_id) + def const_missing(const_name) + # Bypass entire lookup process if we can get the constant from Object. + # This is useful for Ruby 1.9 where Module#const_defined? looks up the + # ancestors in the chain for the constant. + return ::Object.const_get(const_name) if ::Object.const_defined?(const_name) + if [Object, Kernel].include?(self) || parent == self super else begin begin - Dependencies.load_missing_constant self, class_id + Dependencies.load_missing_constant self, const_name rescue NameError - parent.send :const_missing, class_id + parent.send :const_missing, const_name end rescue NameError => e # Make sure that the name we are missing is the one that caused the error - parent_qualified_name = Dependencies.qualified_name_for parent, class_id + parent_qualified_name = Dependencies.qualified_name_for parent, const_name raise unless e.missing_name? parent_qualified_name - qualified_name = Dependencies.qualified_name_for self, class_id + qualified_name = Dependencies.qualified_name_for self, const_name raise NameError.new("uninitialized constant #{qualified_name}").copy_blame!(e) end end