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

ruby-changes:42599

From: usa <ko1@a...>
Date: Fri, 22 Apr 2016 13:26:19 +0900 (JST)
Subject: [ruby-changes:42599] usa:r54673 (ruby_2_2): merge revision(s) 53381, 53382, 53511, 53512: [Backport #11916]

usa	2016-04-22 14:22:55 +0900 (Fri, 22 Apr 2016)

  New Revision: 54673

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=54673

  Log:
    merge revision(s) 53381,53382,53511,53512: [Backport #11916]
    
    * lib/forwardable.rb (def_instance_delegator) fix delegating to
      'args' and 'block', clashing with local variables in generated
      methods.  [ruby-core:72579] [Bug #11916]
    
    * lib/forwardable.rb (def_single_delegator): ditto.
    
    * lib/forwardable.rb: Convert given accessors to String.
      r53381 changed to accept only Symbol or String for accessors, but
      there are several rubygems that pass classes (e.g. Array,
      Hash, ...) as accessors. Prior r53381, it was accepted because Class#to_s
      returns its class name. After r53381 given accessors are checked
      with define_method, but it accepts only Symbol or String, otherwise
      raises TypeError.
          def_delegator Foo, :some_method
      This change is to revert unwanted incompatibility. But this behavior
      may change in the future.
      This change is to revert unexpected incompatibility. But this behavior

  Added files:
    branches/ruby_2_2/test/test_forwardable.rb
  Modified directories:
    branches/ruby_2_2/
  Modified files:
    branches/ruby_2_2/ChangeLog
    branches/ruby_2_2/lib/forwardable.rb
    branches/ruby_2_2/version.h
Index: ruby_2_2/ChangeLog
===================================================================
--- ruby_2_2/ChangeLog	(revision 54672)
+++ ruby_2_2/ChangeLog	(revision 54673)
@@ -1,3 +1,27 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/ChangeLog#L1
+Fri Apr 22 14:13:28 2016  sorah (Shota Fukumori)  <her@s...>
+
+	* lib/forwardable.rb: Convert given accessors to String.
+
+	  r53381 changed to accept only Symbol or String for accessors, but
+	  there are several rubygems that pass classes (e.g. Array,
+	  Hash, ...) as accessors. Prior r53381, it was accepted because Class#to_s
+	  returns its class name. After r53381 given accessors are checked
+	  with define_method, but it accepts only Symbol or String, otherwise
+	  raises TypeError.
+
+	      def_delegator Foo, :some_method
+
+	  This change is to revert unexpected incompatibility. But this behavior
+	  may change in the future.
+
+Fri Apr 22 14:13:28 2016  Elliot Winkler  <elliot.winkler@g...>
+
+	* lib/forwardable.rb (def_instance_delegator) fix delegating to
+	  'args' and 'block', clashing with local variables in generated
+	  methods.  [ruby-core:72579] [Bug #11916]
+
+	* lib/forwardable.rb (def_single_delegator): ditto.
+
 Fri Apr 22 13:41:38 2016  Nobuyoshi Nakada  <nobu@r...>
 
 	* compile.c (compile_massign_lhs): when index ends with splat,
Index: ruby_2_2/lib/forwardable.rb
===================================================================
--- ruby_2_2/lib/forwardable.rb	(revision 54672)
+++ ruby_2_2/lib/forwardable.rb	(revision 54673)
@@ -177,6 +177,11 @@ module Forwardable https://github.com/ruby/ruby/blob/trunk/ruby_2_2/lib/forwardable.rb#L177
   #   q.push 23  #=> NoMethodError
   #
   def def_instance_delegator(accessor, method, ali = method)
+    accessor = accessor.to_s
+    if method_defined?(accessor) || private_method_defined?(accessor)
+      accessor = "#{accessor}()"
+    end
+
     line_no = __LINE__; str = %{
       def #{ali}(*args, &block)
         begin
@@ -269,7 +274,12 @@ module SingleForwardable https://github.com/ruby/ruby/blob/trunk/ruby_2_2/lib/forwardable.rb#L274
   # the method of the same name in _accessor_).  If _new_name_ is
   # provided, it is used as the name for the delegate method.
   def def_single_delegator(accessor, method, ali = method)
-    str = %{
+    accessor = accessor.to_s
+    if method_defined?(accessor) || private_method_defined?(accessor)
+      accessor = "#{accessor}()"
+    end
+
+    line_no = __LINE__; str = %{
       def #{ali}(*args, &block)
         begin
           #{accessor}.__send__(:#{method}, *args, &block)
@@ -280,7 +290,7 @@ module SingleForwardable https://github.com/ruby/ruby/blob/trunk/ruby_2_2/lib/forwardable.rb#L290
       end
     }
 
-    instance_eval(str, __FILE__, __LINE__)
+    instance_eval(str, __FILE__, line_no)
   end
 
   alias delegate single_delegate
Index: ruby_2_2/version.h
===================================================================
--- ruby_2_2/version.h	(revision 54672)
+++ ruby_2_2/version.h	(revision 54673)
@@ -1,6 +1,6 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/version.h#L1
 #define RUBY_VERSION "2.2.5"
 #define RUBY_RELEASE_DATE "2016-04-22"
-#define RUBY_PATCHLEVEL 294
+#define RUBY_PATCHLEVEL 295
 
 #define RUBY_RELEASE_YEAR 2016
 #define RUBY_RELEASE_MONTH 4
Index: ruby_2_2/test/test_forwardable.rb
===================================================================
--- ruby_2_2/test/test_forwardable.rb	(revision 0)
+++ ruby_2_2/test/test_forwardable.rb	(revision 54673)
@@ -0,0 +1,229 @@ https://github.com/ruby/ruby/blob/trunk/ruby_2_2/test/test_forwardable.rb#L1
+# frozen_string_literal: false
+require 'test/unit'
+require 'forwardable'
+
+class TestForwardable < Test::Unit::TestCase
+  RECEIVER = BasicObject.new
+  RETURNED1 = BasicObject.new
+  RETURNED2 = BasicObject.new
+
+  class << RECEIVER
+    def delegated1
+      RETURNED1
+    end
+
+    def delegated2
+      RETURNED2
+    end
+  end
+
+  def test_def_instance_delegator
+    %i[def_delegator def_instance_delegator].each do |m|
+      cls = forwardable_class do
+        __send__ m, :@receiver, :delegated1
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+    end
+  end
+
+  def test_def_instance_delegator_using_args_method_as_receiver
+    %i[def_delegator def_instance_delegator].each do |m|
+      cls = forwardable_class(
+        receiver_name: :args,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, :args, :delegated1
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+    end
+  end
+
+  def test_def_instance_delegator_using_block_method_as_receiver
+    %i[def_delegator def_instance_delegator].each do |m|
+      cls = forwardable_class(
+        receiver_name: :block,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, :block, :delegated1
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+    end
+  end
+
+  def test_def_instance_delegators
+    %i[def_delegators def_instance_delegators].each do |m|
+      cls = forwardable_class do
+        __send__ m, :@receiver, :delegated1, :delegated2
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_def_instance_delegators_using_args_method_as_receiver
+    %i[def_delegators def_instance_delegators].each do |m|
+      cls = forwardable_class(
+        receiver_name: :args,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, :args, :delegated1, :delegated2
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_def_instance_delegators_using_block_method_as_receiver
+    %i[def_delegators def_instance_delegators].each do |m|
+      cls = forwardable_class(
+        receiver_name: :block,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, :block, :delegated1, :delegated2
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_instance_delegate
+    %i[delegate instance_delegate].each do |m|
+      cls = forwardable_class do
+        __send__ m, delegated1: :@receiver, delegated2: :@receiver
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+
+      cls = forwardable_class do
+        __send__ m, %i[delegated1 delegated2] => :@receiver
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_def_instance_delegate_using_args_method_as_receiver
+    %i[delegate instance_delegate].each do |m|
+      cls = forwardable_class(
+        receiver_name: :args,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, delegated1: :args, delegated2: :args
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_def_instance_delegate_using_block_method_as_receiver
+    %i[delegate instance_delegate].each do |m|
+      cls = forwardable_class(
+        receiver_name: :block,
+        type: :method,
+        visibility: :private
+      ) do
+        __send__ m, delegated1: :block, delegated2: :block
+      end
+
+      assert_same RETURNED1, cls.new.delegated1
+      assert_same RETURNED2, cls.new.delegated2
+    end
+  end
+
+  def test_def_single_delegator
+    %i[def_delegator def_single_delegator].each do |m|
+      cls = single_forwardable_class do
+        __send__ m, :@receiver, :delegated1
+      end
+
+      assert_same RETURNED1, cls.delegated1
+    end
+  end
+
+  def test_def_single_delegators
+    %i[def_delegators def_single_delegators].each do |m|
+      cls = single_forwardable_class do
+        __send__ m, :@receiver, :delegated1, :delegated2
+      end
+
+      assert_same RETURNED1, cls.delegated1
+      assert_same RETURNED2, cls.delegated2
+    end
+  end
+
+  def test_single_delegate
+    %i[delegate single_delegate].each do |m|
+      cls = single_forwardable_class do
+        __send__ m, delegated1: :@receiver, delegated2: :@receiver
+      end
+
+      assert_same RETURNED1, cls.delegated1
+      assert_same RETURNED2, cls.delegated2
+
+      cls = single_forwardable_class do
+        __send__ m, %i[delegated1 delegated2] => :@receiver
+      end
+
+      assert_same RETURNED1, cls.delegated1
+      assert_same RETURNED2, cls.delegated2
+    end
+  end
+
+  class Foo
+    extend Forwardable
+
+    def_delegator :bar, :baz
+    def_delegator :caller, :itself, :c
+
+    class Exception
+    end
+  end
+
+  private
+
+  def forwardable_class(
+    receiver_name: :receiver,
+    type: :ivar,
+    visibility: :public,
+    &block
+  )
+    Class.new do
+      extend Forwardable
+
+      define_method(:initialize) do
+        instance_variable_set("@#{receiver_name}", RECEIVER)
+      end
+
+      if type == :method
+        attr_reader(receiver_name)
+        __send__(visibility, receiver_name)
+      end
+
+      class_exec(&block)
+    end
+  end
+
+  def single_forwardable_class(&block)
+    Class.new do
+      extend SingleForwardable
+
+      @receiver = RECEIVER
+
+      class_exec(&block)
+    end
+  end
+end

Property changes on: ruby_2_2
___________________________________________________________________
Modified: svn:mergeinfo
   Merged /trunk:r53381-53382,53511-53512


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

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