Ensure that constantize just rescues NameError that applies to the constant being currently loaded.

This commit is contained in:
José Valim 2011-09-23 16:16:53 +02:00
parent 310565f537
commit b2f34d1e35
2 changed files with 26 additions and 4 deletions

View File

@ -245,12 +245,15 @@ module ActiveSupport
# "blargle".safe_constantize # => nil
def safe_constantize(camel_cased_word)
begin
camel_cased_word.constantize
rescue NameError
nil
constantize(camel_cased_word)
rescue NameError => e
raise unless e.message =~ /uninitialized constant #{const_regexp(camel_cased_word)}$/ ||
e.name.to_s == camel_cased_word.to_s
rescue ArgumentError => e
raise unless e.message =~ /not missing constant #{const_regexp(camel_cased_word)}\!$/
end
end
# Turns a number into an ordinal string used to denote the position in an
# ordered sequence such as 1st, 2nd, 3rd, 4th.
#
@ -273,5 +276,18 @@ module ActiveSupport
end
end
end
private
# Mount a regular expression that will match part by part of the constant.
# For instance, Foo::Bar::Baz will generate Foo(::Bar(::Baz)?)?
def const_regexp(camel_cased_word) #:nodoc:
parts = camel_cased_word.split("::")
last = parts.pop
parts.reverse.inject(last) do |acc, part|
part.empty? ? acc : "#{part}(::#{acc})?"
end
end
end
end

View File

@ -12,8 +12,11 @@ module ConstantizeTestCases
assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") }
assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") }
assert_raise(NameError) { yield("UnknownClass") }
assert_raise(NameError) { yield("UnknownClass::Ace") }
assert_raise(NameError) { yield("UnknownClass::Ace::Base") }
assert_raise(NameError) { yield("An invalid string") }
assert_raise(NameError) { yield("InvalidClass\n") }
assert_raise(NameError) { yield("Ace::ConstantizeTestCases") }
assert_raise(NameError) { yield("Ace::Base::ConstantizeTestCases") }
end
@ -23,9 +26,12 @@ module ConstantizeTestCases
assert_nothing_raised { assert_equal ConstantizeTestCases, yield("ConstantizeTestCases") }
assert_nothing_raised { assert_equal ConstantizeTestCases, yield("::ConstantizeTestCases") }
assert_nothing_raised { assert_equal nil, yield("UnknownClass") }
assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace") }
assert_nothing_raised { assert_equal nil, yield("UnknownClass::Ace::Base") }
assert_nothing_raised { assert_equal nil, yield("An invalid string") }
assert_nothing_raised { assert_equal nil, yield("InvalidClass\n") }
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") }
end
end