diff options
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | lib/forwardable.rb | 2 | ||||
-rw-r--r-- | test/test_forwardable.rb | 104 | ||||
-rw-r--r-- | version.h | 2 |
4 files changed, 120 insertions, 4 deletions
@@ -1,3 +1,19 @@ +Sat Apr 23 00:13:50 2016 sorah (Shota Fukumori) <her@sorah.jp> + + * 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. + Sat Apr 23 00:02:09 2016 Nobuyoshi Nakada <nobu@ruby-lang.org> * configure.in: check if succeeded in creating config.h. diff --git a/lib/forwardable.rb b/lib/forwardable.rb index f27437af82..e20f5e3a31 100644 --- a/lib/forwardable.rb +++ b/lib/forwardable.rb @@ -178,6 +178,7 @@ module Forwardable # 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 @@ -274,6 +275,7 @@ module SingleForwardable # 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) + accessor = accessor.to_s if method_defined?(accessor) || private_method_defined?(accessor) accessor = "#{accessor}()" end diff --git a/test/test_forwardable.rb b/test/test_forwardable.rb index a3d03f438b..a474e4ad76 100644 --- a/test/test_forwardable.rb +++ b/test/test_forwardable.rb @@ -27,6 +27,34 @@ class TestForwardable < Test::Unit::TestCase 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 @@ -38,6 +66,36 @@ class TestForwardable < Test::Unit::TestCase 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 @@ -56,6 +114,36 @@ class TestForwardable < Test::Unit::TestCase 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 @@ -126,12 +214,22 @@ class TestForwardable < Test::Unit::TestCase private - def forwardable_class(&block) + def forwardable_class( + receiver_name: :receiver, + type: :ivar, + visibility: :public, + &block + ) Class.new do extend Forwardable - def initialize - @receiver = RECEIVER + 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) @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.3.0" #define RUBY_RELEASE_DATE "2016-04-23" -#define RUBY_PATCHLEVEL 100 +#define RUBY_PATCHLEVEL 101 #define RUBY_RELEASE_YEAR 2016 #define RUBY_RELEASE_MONTH 4 |