From fc4de12302ab0e83e2bd0c76b9c3d4e7b3cbfee8 Mon Sep 17 00:00:00 2001 From: nobu Date: Wed, 4 Dec 2013 03:47:57 +0000 Subject: delegate.rb: ignore unset target * lib/delegate.rb (Delegator#method_missing): ignore the target if not set, and delegate to global methods. [ruby-core:58572] [Bug #9155] * lib/delegate.rb (Delegator#respond_to_missing): ditto. * lib/delegate.rb (SimpleDelegator#__getobj__): yield and return if not delegated but a block is given, like as Hash#fetch. * lib/delegate.rb (DelegateClass#__getobj__): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@43984 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 12 ++++++++++++ lib/delegate.rb | 21 +++++++++++++++------ test/test_delegate.rb | 12 ++++++++++++ 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/ChangeLog b/ChangeLog index 258b6d1af6..f8e29ccf01 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +Wed Dec 4 12:47:54 2013 Nobuyoshi Nakada + + * lib/delegate.rb (Delegator#method_missing): ignore the target if not + set, and delegate to global methods. [ruby-core:58572] [Bug #9155] + + * lib/delegate.rb (Delegator#respond_to_missing): ditto. + + * lib/delegate.rb (SimpleDelegator#__getobj__): yield and return if + not delegated but a block is given, like as Hash#fetch. + + * lib/delegate.rb (DelegateClass#__getobj__): ditto. + Tue Dec 3 23:48:18 2013 Nobuyoshi Nakada * configure.in: check malloc_size() available on BSD. diff --git a/lib/delegate.rb b/lib/delegate.rb index 0eaf37122b..c33f7e40df 100644 --- a/lib/delegate.rb +++ b/lib/delegate.rb @@ -74,9 +74,10 @@ class Delegator < BasicObject # Handles the magic of delegation through \_\_getobj\_\_. # def method_missing(m, *args, &block) - target = self.__getobj__ + r = true + target = self.__getobj__ {r = false} begin - if target.respond_to?(m) + if r && target.respond_to?(m) target.__send__(m, *args, &block) elsif ::Kernel.respond_to?(m, true) ::Kernel.instance_method(m).bind(self).(*args, &block) @@ -93,8 +94,10 @@ class Delegator < BasicObject # call through \_\_getobj\_\_. # def respond_to_missing?(m, include_private) - r = self.__getobj__.respond_to?(m, include_private) - if r && include_private && !self.__getobj__.respond_to?(m, false) + r = true + target = self.__getobj__ {r = false} + r &&= target.respond_to?(m, include_private) + if r && include_private && !target.respond_to?(m, false) warn "#{caller(3)[0]}: delegator does not forward private method \##{m}" return false end @@ -306,7 +309,10 @@ end class SimpleDelegator