diff options
Diffstat (limited to 'lib/delegate.rb')
-rw-r--r-- | lib/delegate.rb | 18 |
1 files changed, 14 insertions, 4 deletions
diff --git a/lib/delegate.rb b/lib/delegate.rb index a1589ecd08..7a2ad50ac3 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -79,10 +79,10 @@ class Delegator < BasicObject r = true target = self.__getobj__ {r = false} - if r && target.respond_to?(m) + if r && target_respond_to?(target, m, false) target.__send__(m, *args, &block) elsif ::Kernel.method_defined?(m) || ::Kernel.private_method_defined?(m) - ::Kernel.instance_method(m).bind(self).(*args, &block) + ::Kernel.instance_method(m).bind_call(self, *args, &block) else super(m, *args, &block) end @@ -95,14 +95,24 @@ class Delegator < BasicObject def respond_to_missing?(m, include_private) r = true target = self.__getobj__ {r = false} - r &&= target.respond_to?(m, include_private) - if r && include_private && !target.respond_to?(m, false) + r &&= target_respond_to?(target, m, include_private) + if r && include_private && !target_respond_to?(target, m, false) warn "delegator does not forward private method \##{m}", uplevel: 3 return false end r end + # Handle BasicObject instances + private def target_respond_to?(target, m, include_private) + case target + when Object + target.respond_to?(m, include_private) + else + ::Kernel.instance_method(:respond_to?).bind_call(target, m, include_private) + end + end + # # Returns the methods available to this delegate object as the union # of this object's and \_\_getobj\_\_ methods. |