Skip to content

Commit

Permalink
Avoid relying on error messages when rescuing
Browse files Browse the repository at this point in the history
When we are rescuing from an error, it's a brittle approach to do checks
with regular expressions on the raised message because it may change in
in the future and error messages are different across implementations.

The NameError API could be improved at the MRI level but for now we need
to rely on its #name. A #== check will only pass for top level constants
or only when the last constant of the path is missing so we need to rely
on #include? instead. For instance:

    begin
      Namespace::Foo
    rescue NameError => e
      e.name # => :Namespace
    end

However, if the name-space already exists, only the name of the first
missing constant in the path is returned (e.g. for Math::PHI, the name
would be :PHI). JRuby will return a fully qualified name (:"Math::PHI").

We need to keep the == check for 1.9 compatibility since const_get will
raise a NameError with a name attribute set to the given string if it's
one of "::" or "".

See http://git.io/jnSN7g for further information.
  • Loading branch information
robin850 authored and rafaelfranca committed Dec 25, 2015
1 parent 7fd06ee commit 766a0cd
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions activesupport/lib/active_support/inflector/methods.rb
Expand Up @@ -280,8 +280,8 @@ def constantize(camel_cased_word)
def safe_constantize(camel_cased_word)
constantize(camel_cased_word)
rescue NameError => e
raise unless e.message =~ /(uninitialized constant|wrong constant name) #{const_regexp(camel_cased_word)}$/ ||
e.name.to_s == camel_cased_word.to_s
raise if e.name && !(camel_cased_word.to_s.split("::").include?(e.name.to_s) ||
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
Expand Down

0 comments on commit 766a0cd

Please sign in to comment.