diff options
| -rw-r--r-- | activesupport/lib/active_support/core_ext/module/delegation.rb | 42 | ||||
| -rw-r--r-- | activesupport/test/core_ext/module_test.rb | 10 | 
2 files changed, 32 insertions, 20 deletions
diff --git a/activesupport/lib/active_support/core_ext/module/delegation.rb b/activesupport/lib/active_support/core_ext/module/delegation.rb index 58146cdf7a..f855833a24 100644 --- a/activesupport/lib/active_support/core_ext/module/delegation.rb +++ b/activesupport/lib/active_support/core_ext/module/delegation.rb @@ -178,30 +178,32 @@ class Module        # whereas conceptually, from the user point of view, the delegator should        # be doing one call.        if allow_nil -        module_eval(<<-EOS, file, line - 3) -          def #{method_prefix}#{method}(#{definition})        # def customer_name(*args, &block) -            _ = #{to}                                         #   _ = client -            if !_.nil? || nil.respond_to?(:#{method})         #   if !_.nil? || nil.respond_to?(:name) -              _.#{method}(#{definition})                      #     _.name(*args, &block) -            end                                               #   end -          end                                                 # end -        EOS +        method_def = [ +          "def #{method_prefix}#{method}(#{definition})",  # def customer_name(*args, &block) +          "_ = #{to}",                                     #   _ = client +          "if !_.nil? || nil.respond_to?(:#{method})",     #   if !_.nil? || nil.respond_to?(:name) +          "  _.#{method}(#{definition})",                  #     _.name(*args, &block) +          "end",                                           #   end +        "end"                                              # end +        ].join ';'        else          exception = %(raise DelegationError, "#{self}##{method_prefix}#{method} delegated to #{to}.#{method}, but #{to} is nil: \#{self.inspect}") -        module_eval(<<-EOS, file, line - 2) -          def #{method_prefix}#{method}(#{definition})                                          # def customer_name(*args, &block) -            _ = #{to}                                                                           #   _ = client -            _.#{method}(#{definition})                                                          #   _.name(*args, &block) -          rescue NoMethodError => e                                                             # rescue NoMethodError => e -            if _.nil? && e.name == :#{method}                                                   #   if _.nil? && e.name == :name -              #{exception}                                                                      #     # add helpful message to the exception -            else                                                                                #   else -              raise                                                                             #     raise -            end                                                                                 #   end -          end                                                                                   # end -        EOS +        method_def = [ +          "def #{method_prefix}#{method}(#{definition})",  # def customer_name(*args, &block) +          " _ = #{to}",                                    #   _ = client +          "  _.#{method}(#{definition})",                  #   _.name(*args, &block) +          "rescue NoMethodError => e",                     # rescue NoMethodError => e +          "  if _.nil? && e.name == :#{method}",           #   if _.nil? && e.name == :name +          "    #{exception}",                              #     # add helpful message to the exception +          "  else",                                        #   else +          "    raise",                                     #     raise +          "  end",                                         #   end +          "end"                                            # end +        ].join ';'        end + +      module_eval(method_def, file, line)      end    end  end diff --git a/activesupport/test/core_ext/module_test.rb b/activesupport/test/core_ext/module_test.rb index 5b99fae411..4680fe5dfe 100644 --- a/activesupport/test/core_ext/module_test.rb +++ b/activesupport/test/core_ext/module_test.rb @@ -245,6 +245,16 @@ class ModuleTest < ActiveSupport::TestCase      end    end +  def test_delegation_line_number +    file, line = Someone.instance_method(:foo).source_location +    assert_equal Someone::FAILED_DELEGATE_LINE, line +  end + +  def test_delegate_line_with_nil +    file, line = Someone.instance_method(:bar).source_location +    assert_equal Someone::FAILED_DELEGATE_LINE_2, line +  end +    def test_delegation_exception_backtrace      someone = Someone.new("foo", "bar")      someone.foo  | 
