diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-22 08:29:02 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-11-22 08:29:02 +0000 |
commit | 16a642c3315832992b2af401a45b02451c23f165 (patch) | |
tree | 1174cbabea6aa7eadff084d2df8a110707d8b12f | |
parent | 633fef6dec9f078d7c02b737a76f3aad0ba5ccc8 (diff) |
Enable refinements at Object#respond_to?
[Feature #15327] [Fix GH-2020]
From: osyo-manga <manga.osyo@gmail.com>
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@65920 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | spec/ruby/core/module/refine_spec.rb | 43 | ||||
-rw-r--r-- | test/ruby/test_refinement.rb | 4 | ||||
-rw-r--r-- | vm_method.c | 9 |
4 files changed, 44 insertions, 14 deletions
@@ -20,6 +20,8 @@ sufficient information, see the ChangeLog file or Redmine * refinements takes place at Kernel#public_send. [Feature #15326] +* refinements takes place at Kernel#respond_to?. [Feature #15327] + * +else+ without +rescue+ now causes a syntax error. [EXPERIMENTAL] * constant names may start with a non-ASCII capital letter. [Feature #13770] diff --git a/spec/ruby/core/module/refine_spec.rb b/spec/ruby/core/module/refine_spec.rb index 97645e5466..3fa493b1da 100644 --- a/spec/ruby/core/module/refine_spec.rb +++ b/spec/ruby/core/module/refine_spec.rb @@ -524,21 +524,42 @@ describe "Module#refine" do }.should raise_error(NameError, /undefined method `foo'/) end - it "is not honored by Kernel#respond_to?" do - klass = Class.new - refinement = Module.new do - refine klass do - def foo; end + ruby_version_is "" ... "2.6" do + it "is not honored by Kernel#respond_to?" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end + end end - end - result = nil - Module.new do - using refinement - result = klass.new.respond_to?(:foo) + result = nil + Module.new do + using refinement + result = klass.new.respond_to?(:foo) + end + + result.should == false end + end + + ruby_version_is "2.6" do + it "is honored by Kernel#respond_to?" do + klass = Class.new + refinement = Module.new do + refine klass do + def foo; end + end + end - result.should == false + result = nil + Module.new do + using refinement + result = klass.new.respond_to?(:foo) + end + + result.should == true + end end end diff --git a/test/ruby/test_refinement.rb b/test/ruby/test_refinement.rb index 11eea720bd..06150d998f 100644 --- a/test/ruby/test_refinement.rb +++ b/test/ruby/test_refinement.rb @@ -326,9 +326,9 @@ class TestRefinement < Test::Unit::TestCase end end - def test_respond_to_should_not_use_refinements + def test_respond_to_should_use_refinements assert_equal(false, 1.respond_to?(:foo)) - assert_equal(false, eval_using(IntegerFooExt, "1.respond_to?(:foo)")) + assert_equal(true, eval_using(IntegerFooExt, "1.respond_to?(:foo)")) end module StringCmpExt diff --git a/vm_method.c b/vm_method.c index c4f41bc118..0aeac2869e 100644 --- a/vm_method.c +++ b/vm_method.c @@ -1089,7 +1089,14 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi) int rb_method_boundp(VALUE klass, ID id, int ex) { - const rb_method_entry_t *me = rb_method_entry_without_refinements(klass, id, NULL); + const rb_method_entry_t *me; + + if (ex & BOUND_RESPONDS) { + me = method_entry_resolve_refinement(klass, id, TRUE, NULL); + } + else { + me = rb_method_entry_without_refinements(klass, id, NULL); + } if (me != 0) { if ((ex & ~BOUND_RESPONDS) && |