Skip to content

Commit

Permalink
Make constantize look down the ancestor chain (excluding Object)
Browse files Browse the repository at this point in the history
  • Loading branch information
marcandre authored and pixeltrix committed May 19, 2012
1 parent 1551de3 commit 99e9a73
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
14 changes: 13 additions & 1 deletion activesupport/lib/active_support/inflector/methods.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
17 changes: 17 additions & 0 deletions activesupport/test/constantize_test_cases.rb
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
module Ace
module Base
class Case
class Dice
end
end
class Fase < Case
end
end
class Gas
include Base
end
end

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") }
Expand All @@ -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") }
Expand All @@ -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("#<Class:0x7b8b718b>::Nested_1") }
end
end

0 comments on commit 99e9a73

Please sign in to comment.