summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog16
-rw-r--r--lib/forwardable.rb2
-rw-r--r--test/test_forwardable.rb104
-rw-r--r--version.h2
4 files changed, 120 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index 3bf8081fd4..a4a678e27a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
diff --git a/version.h b/version.h
index c4200beeb4..69160a4641 100644
--- a/version.h
+++ b/version.h
@@ -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