diff options
Diffstat (limited to 'activesupport/lib/active_support/core_ext/module')
-rw-r--r-- | activesupport/lib/active_support/core_ext/module/delegation.rb | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 24df83800b..a5f4d03256 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -185,19 +185,31 @@ class Module # On the other hand it could be that the target has side-effects, # whereas conceptually, from the user point of view, the delegator should # be doing one call. - - exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") - - method_def = [ - "def #{method_prefix}#{method}(#{definition})", - " _ = #{to}", - " if !_.nil? || nil.respond_to?(:#{method})", - " _.#{method}(#{definition})", - " else", - " #{exception unless allow_nil}", - " end", + if allow_nil + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + "_ = #{to}", + "if !_.nil? || nil.respond_to?(:#{method})", + " _.#{method}(#{definition})", + "end", "end" - ].join ';' + ].join ';' + else + exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") + + method_def = [ + "def #{method_prefix}#{method}(#{definition})", + " _ = #{to}", + " _.#{method}(#{definition})", + "rescue NoMethodError => e", + " if _.nil? && e.name == :#{method}", + " #{exception}", + " else", + " raise", + " end", + "end" + ].join ';' + end module_eval(method_def, file, line) end |