From 99e9a733c8852f4ff065f2ede9c9cd03475411a2 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune Date: Fri, 4 May 2012 23:57:11 -0400 Subject: [PATCH] Make constantize look down the ancestor chain (excluding Object) --- .../lib/active_support/inflector/methods.rb | 14 +++++++++++++- activesupport/test/constantize_test_cases.rb | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/activesupport/lib/active_support/inflector/methods.rb b/activesupport/lib/active_support/inflector/methods.rb index 48296841aabe..274dc90effc4 100644 --- a/activesupport/lib/active_support/inflector/methods.rb +++ b/activesupport/lib/active_support/inflector/methods.rb @@ -203,7 +203,19 @@ def constantize(camel_cased_word) #:nodoc: names.shift if names.empty? || names.first.empty? names.inject(Object) do |constant, name| - constant.const_get(name, false) + candidate = constant.const_get(name) + if constant.const_defined?(name, false) || !Object.const_defined?(name) + candidate + else + # Go down the ancestors to check it it's owned + # directly before we reach Object or the end of ancestors. + constant.ancestors.each do |ancestor| + break if ancestor == Object + return candidate if ancestor.const_defined?(name, false) + end + # owner is in Object, so raise + constant.const_get(name, false) + end end end diff --git a/activesupport/test/constantize_test_cases.rb b/activesupport/test/constantize_test_cases.rb index 135f894056a4..908f9e9a3793 100644 --- a/activesupport/test/constantize_test_cases.rb +++ b/activesupport/test/constantize_test_cases.rb @@ -1,7 +1,14 @@ module Ace module Base class Case + class Dice + end end + class Fase < Case + end + end + class Gas + include Base end end @@ -9,6 +16,9 @@ module ConstantizeTestCases def run_constantize_tests_on assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } + assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } + assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } assert_raise(NameError) { yield("UnknownClass") } @@ -18,11 +28,16 @@ def run_constantize_tests_on assert_raise(NameError) { yield("InvalidClass\n") } assert_raise(NameError) { yield("Ace::ConstantizeTestCases") } assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") } + assert_raise(NameError) { yield("Ace::Gas::Base") } + assert_raise(NameError) { yield("Ace::Gas::ConstantizeTestCases") } end def run_safe_constantize_tests_on assert_nothing_raised { assert_equal Ace::Base::Case, yield("Ace::Base::Case") } assert_nothing_raised { assert_equal Ace::Base::Case, yield("::Ace::Base::Case") } + assert_nothing_raised { assert_equal Ace::Base::Case::Dice, yield("Ace::Base::Case::Dice") } + assert_nothing_raised { assert_equal Ace::Base::Fase::Dice, yield("Ace::Base::Fase::Dice") } + assert_nothing_raised { assert_equal Ace::Gas::Case, yield("Ace::Gas::Case") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") } assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("UnknownClass") } @@ -33,6 +48,8 @@ def run_safe_constantize_tests_on assert_nothing_raised { assert_equal nil, yield("blargle") } assert_nothing_raised { assert_equal nil, yield("Ace::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("Ace::Base::ConstantizeTestCases") } + assert_nothing_raised { assert_equal nil, yield("Ace::Gas::Base") } + assert_nothing_raised { assert_equal nil, yield("Ace::Gas::ConstantizeTestCases") } assert_nothing_raised { assert_equal nil, yield("#::Nested_1") } end end