[前][次][番号順一覧][スレッド一覧]

ruby-changes:33666

From: usa <ko1@a...>
Date: Wed, 30 Apr 2014 15:32:31 +0900 (JST)
Subject: [ruby-changes:33666] usa:r45747 (ruby_2_0_0): merge revision(s) 43682, 43727, 43752, 43759: [Backport #9560]

usa	2014-04-30 15:32:24 +0900 (Wed, 30 Apr 2014)

  New Revision: 45747

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45747

  Log:
    merge revision(s) 43682,43727,43752,43759: [Backport #9560]
    
    * lib/delegate.rb (Delegator#send): override to get rid of global function interference.
      [Fixes GH-449]
    
    * lib/delegate.rb (Delegator#send): separate from method_missing so
      that super calls proper method.
    
    * lib/delegate.rb (Delegator#method_missing): try private methods defined in
      Kernel after the target.  [Fixes GH-449]
    
    * lib/delegate.rb (SimpleDelegator#__getobj__): target object must be set.
    
    * lib/delegate.rb (DelegateClass#__getobj__): ditto.

  Modified directories:
    branches/ruby_2_0_0/
  Modified files:
    branches/ruby_2_0_0/ChangeLog
    branches/ruby_2_0_0/lib/delegate.rb
    branches/ruby_2_0_0/test/ruby/envutil.rb
    branches/ruby_2_0_0/test/test_delegate.rb
    branches/ruby_2_0_0/version.h
Index: ruby_2_0_0/ChangeLog
===================================================================
--- ruby_2_0_0/ChangeLog	(revision 45746)
+++ ruby_2_0_0/ChangeLog	(revision 45747)
@@ -1,3 +1,24 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/ChangeLog#L1
+Wed Apr 30 15:20:44 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/delegate.rb (SimpleDelegator#__getobj__): target object must be set.
+
+	* lib/delegate.rb (DelegateClass#__getobj__): ditto.
+
+Wed Apr 30 15:20:44 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/delegate.rb (Delegator#method_missing): try private methods defined in
+	  Kernel after the target.  [Fixes GH-449]
+
+Wed Apr 30 15:20:44 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/delegate.rb (Delegator#send): separate from method_missing so
+	  that super calls proper method.
+
+Wed Apr 30 15:20:44 2014  Nobuyoshi Nakada  <nobu@r...>
+
+	* lib/delegate.rb (Delegator#send): override to get rid of global function interference.
+	  [Fixes GH-449]
+
 Wed Apr 30 15:04:25 2014  Nobuyoshi Nakada  <nobu@r...>
 
 	* ext/readline/extconf.rb: fix typo, `$defs` not `$DEFS`.
Index: ruby_2_0_0/lib/delegate.rb
===================================================================
--- ruby_2_0_0/lib/delegate.rb	(revision 45746)
+++ ruby_2_0_0/lib/delegate.rb	(revision 45747)
@@ -43,9 +43,16 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L43
 class Delegator < BasicObject
   kernel = ::Kernel.dup
   kernel.class_eval do
+    alias __raise__ raise
     [:to_s,:inspect,:=~,:!~,:===,:<=>,:eql?,:hash].each do |m|
       undef_method m
     end
+    private_instance_methods.each do |m|
+      if /\Ablock_given\?\z|iterator\?\z|\A__raise__\z/ =~ m
+        next
+      end
+      undef_method m
+    end
   end
   include kernel
 
@@ -69,9 +76,15 @@ class Delegator < BasicObject https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L76
   def method_missing(m, *args, &block)
     target = self.__getobj__
     begin
-      target.respond_to?(m) ? target.__send__(m, *args, &block) : super(m, *args, &block)
+      if target.respond_to?(m)
+        target.__send__(m, *args, &block)
+      elsif ::Kernel.respond_to?(m, true)
+        ::Kernel.instance_method(m).bind(self).(*args, &block)
+      else
+        super(m, *args, &block)
+      end
     ensure
-      $@.delete_if {|t| %r"\A#{Regexp.quote(__FILE__)}:#{__LINE__-2}:"o =~ t} if $@
+      $@.delete_if {|t| %r"\A#{Regexp.quote(__FILE__)}:(?:#{[__LINE__-7, __LINE__-5, __LINE__-3].join('|')}):"o =~ t} if $@
     end
   end
 
@@ -142,7 +155,7 @@ class Delegator < BasicObject https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L155
   # method calls are being delegated to.
   #
   def __getobj__
-    raise NotImplementedError, "need to define `__getobj__'"
+    __raise__ ::NotImplementedError, "need to define `__getobj__'"
   end
 
   #
@@ -150,7 +163,7 @@ class Delegator < BasicObject https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L163
   # to _obj_.
   #
   def __setobj__(obj)
-    raise NotImplementedError, "need to define `__setobj__'"
+    __raise__ ::NotImplementedError, "need to define `__setobj__'"
   end
 
   #
@@ -265,6 +278,7 @@ end https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L278
 class SimpleDelegator<Delegator
   # Returns the current object method calls are being delegated to.
   def __getobj__
+    __raise__ ::ArgumentError, "not delegated" unless defined?(@delegate_sd_obj)
     @delegate_sd_obj
   end
 
@@ -283,7 +297,7 @@ class SimpleDelegator<Delegator https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L297
   #   puts names[1]    # => Sinclair
   #
   def __setobj__(obj)
-    raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
+    __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
     @delegate_sd_obj = obj
   end
 end
@@ -339,10 +353,11 @@ def DelegateClass(superclass) https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/lib/delegate.rb#L353
   methods -= [:to_s,:inspect,:=~,:!~,:===]
   klass.module_eval do
     def __getobj__  # :nodoc:
+      __raise__ ::ArgumentError, "not delegated" unless defined?(@delegate_dc_obj)
       @delegate_dc_obj
     end
     def __setobj__(obj)  # :nodoc:
-      raise ArgumentError, "cannot delegate to self" if self.equal?(obj)
+      __raise__ ::ArgumentError, "cannot delegate to self" if self.equal?(obj)
       @delegate_dc_obj = obj
     end
     methods.each do |method|
Index: ruby_2_0_0/version.h
===================================================================
--- ruby_2_0_0/version.h	(revision 45746)
+++ ruby_2_0_0/version.h	(revision 45747)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/version.h#L1
 #define RUBY_VERSION "2.0.0"
 #define RUBY_RELEASE_DATE "2014-04-30"
-#define RUBY_PATCHLEVEL 467
+#define RUBY_PATCHLEVEL 468
 
 #define RUBY_RELEASE_YEAR 2014
 #define RUBY_RELEASE_MONTH 4
Index: ruby_2_0_0/test/ruby/envutil.rb
===================================================================
--- ruby_2_0_0/test/ruby/envutil.rb	(revision 45746)
+++ ruby_2_0_0/test/ruby/envutil.rb	(revision 45747)
@@ -379,6 +379,29 @@ eom https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/ruby/envutil.rb#L379
         AssertFile
       end
 
+      def assert_raise_with_message(exception, expected, msg = nil, &block)
+        case expected
+        when String
+          assert = :assert_equal
+        when Regexp
+          assert = :assert_match
+        else
+          raise TypeError, "Expected #{expected.inspect} to be a kind of String or Regexp, not #{expected.class}"
+        end
+
+        ex = assert_raise(exception, *msg) {yield}
+        msg = message(msg, "") {"Expected Exception(#{exception}) was raised, but the message doesn't match"}
+
+        if assert == :assert_equal
+          assert_equal(expected, ex.message, msg)
+        else
+          msg = message(msg) { "Expected #{mu_pp expected} to match #{mu_pp ex.message}" }
+          assert expected =~ ex.message, msg
+          block.binding.eval("proc{|_|$~=_}").call($~)
+        end
+        ex
+      end
+
       class << (AssertFile = Struct.new(:message).new)
         include Assertions
         def assert_file_predicate(predicate, *args)
Index: ruby_2_0_0/test/test_delegate.rb
===================================================================
--- ruby_2_0_0/test/test_delegate.rb	(revision 45746)
+++ ruby_2_0_0/test/test_delegate.rb	(revision 45747)
@@ -1,5 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/test_delegate.rb#L1
 require 'test/unit'
 require 'delegate'
+require_relative 'ruby/envutil'
 
 class TestDelegateClass < Test::Unit::TestCase
   module M
@@ -133,4 +134,39 @@ class TestDelegateClass < Test::Unit::Te https://github.com/ruby/ruby/blob/trunk/ruby_2_0_0/test/test_delegate.rb#L134
     assert_raise(NoMethodError, '[ruby-dev:40314]#4') {d.delegate_test_private}
     assert_raise(NoMethodError, '[ruby-dev:40314]#5') {d.send(:delegate_test_private)}
   end
+
+  def test_global_function
+    klass = Class.new do
+      def open
+      end
+    end
+    obj = klass.new
+    d = SimpleDelegator.new(obj)
+    assert_nothing_raised(ArgumentError) {obj.open}
+    assert_nothing_raised(ArgumentError) {d.open}
+    assert_nothing_raised(ArgumentError) {d.send(:open)}
+  end
+
+  def test_send_method_in_delegator
+    d = Class.new(SimpleDelegator) do
+      def foo
+        "foo"
+      end
+    end.new(Object.new)
+    assert_equal("foo", d.send(:foo))
+  end
+
+  def test_unset_simple_delegator
+    d = SimpleDelegator.allocate
+    assert_raise_with_message(ArgumentError, /not delegated/) {
+      d.__getobj__
+    }
+  end
+
+  def test_unset_delegate_class
+    d = IV.allocate
+    assert_raise_with_message(ArgumentError, /not delegated/) {
+      d.__getobj__
+    }
+  end
 end

Property changes on: ruby_2_0_0
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r43682,43727,43752,43759


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]