Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Ensure that constantize just rescues NameError that applies to the co…

…nstant being currently loaded.
  • Loading branch information...
commit b2f34d1e3591df0f19f01ba30160661175c9a6b6 1 parent 310565f
@josevalim josevalim authored
View
24 activesupport/lib/active_support/inflector/methods.rb
@@ -245,12 +245,15 @@ def constantize(camel_cased_word) #:nodoc:
# "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 @@ def ordinalize(number)
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
6 activesupport/test/constantize_test_cases.rb
@@ -12,8 +12,11 @@ def run_constantize_tests_on
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 @@ def run_safe_constantize_tests_on
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

1 comment on commit b2f34d1

@mike-burns

Rails: now with more #try in more places!

Please sign in to comment.
Something went wrong with that request. Please try again.