1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

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
This commit is contained in:
nobu 2018-11-22 08:29:02 +00:00
parent 633fef6dec
commit 16a642c331
4 changed files with 45 additions and 15 deletions

2
NEWS
View file

@ -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#public_send. [Feature #15326]
* refinements takes place at Kernel#respond_to?. [Feature #15327]
* +else+ without +rescue+ now causes a syntax error. [EXPERIMENTAL] * +else+ without +rescue+ now causes a syntax error. [EXPERIMENTAL]
* constant names may start with a non-ASCII capital letter. [Feature #13770] * constant names may start with a non-ASCII capital letter. [Feature #13770]

View file

@ -524,21 +524,42 @@ describe "Module#refine" do
}.should raise_error(NameError, /undefined method `foo'/) }.should raise_error(NameError, /undefined method `foo'/)
end end
it "is not honored by Kernel#respond_to?" do ruby_version_is "" ... "2.6" do
klass = Class.new it "is not honored by Kernel#respond_to?" do
refinement = Module.new do klass = Class.new
refine klass do refinement = Module.new do
def foo; end refine klass do
def foo; end
end
end end
end
result = nil result = nil
Module.new do Module.new do
using refinement using refinement
result = klass.new.respond_to?(:foo) result = klass.new.respond_to?(:foo)
end end
result.should == false 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 = nil
Module.new do
using refinement
result = klass.new.respond_to?(:foo)
end
result.should == true
end
end end
end end

View file

@ -326,9 +326,9 @@ class TestRefinement < Test::Unit::TestCase
end end
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, 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 end
module StringCmpExt module StringCmpExt

View file

@ -1089,7 +1089,14 @@ rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
int int
rb_method_boundp(VALUE klass, ID id, int ex) 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 (me != 0) {
if ((ex & ~BOUND_RESPONDS) && if ((ex & ~BOUND_RESPONDS) &&