ruby-changes:31905
From: nobu <ko1@a...>
Date: Wed, 4 Dec 2013 12:48:05 +0900 (JST)
Subject: [ruby-changes:31905] nobu:r43984 (trunk): delegate.rb: ignore unset target
nobu 2013-12-04 12:47:57 +0900 (Wed, 04 Dec 2013) New Revision: 43984 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=43984 Log: 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. Modified files: trunk/ChangeLog trunk/lib/delegate.rb trunk/test/test_delegate.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 43983) +++ ChangeLog (revision 43984) @@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Wed Dec 4 12:47:54 2013 Nobuyoshi Nakada <nobu@r...> + + * 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 <nobu@r...> * configure.in: check malloc_size() available on BSD. Index: lib/delegate.rb =================================================================== --- lib/delegate.rb (revision 43983) +++ lib/delegate.rb (revision 43984) @@ -74,9 +74,10 @@ class Delegator < BasicObject https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L74 # 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 https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L94 # 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 https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L309 class SimpleDelegator<Delegator # Returns the current object method calls are being delegated to. def __getobj__ - __raise__ ::ArgumentError, "not delegated" unless defined?(@delegate_sd_obj) + unless defined?(@delegate_sd_obj) + return yield if block_given? + __raise__ ::ArgumentError, "not delegated" + end @delegate_sd_obj end @@ -381,7 +387,10 @@ def DelegateClass(superclass) https://github.com/ruby/ruby/blob/trunk/lib/delegate.rb#L387 methods -= [:to_s,:inspect,:=~,:!~,:===] klass.module_eval do def __getobj__ # :nodoc: - __raise__ ::ArgumentError, "not delegated" unless defined?(@delegate_dc_obj) + unless defined?(@delegate_dc_obj) + return yield if block_given? + __raise__ ::ArgumentError, "not delegated" + end @delegate_dc_obj end def __setobj__(obj) # :nodoc: Index: test/test_delegate.rb =================================================================== --- test/test_delegate.rb (revision 43983) +++ test/test_delegate.rb (revision 43984) @@ -168,4 +168,16 @@ class TestDelegateClass < Test::Unit::Te https://github.com/ruby/ruby/blob/trunk/test/test_delegate.rb#L168 d.__getobj__ } end + + class Bug9155 < DelegateClass(Integer) + def initialize(value) + super(Integer(value)) + end + end + + def test_global_method_if_no_target + bug9155 = '[ruby-core:58572] [Bug #9155]' + x = assert_nothing_raised(ArgumentError, bug9155) {break Bug9155.new(1)} + assert_equal(1, x.to_i, bug9155) + end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/