summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2021-02-28 14:53:21 +0000
committerusa <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2021-02-28 14:53:21 +0000
commit4be089c0dd720324730230c1abfe0c200d125359 (patch)
tree543ebfd021b28ab90d7f3204b96f9574128048ea
parente31ab1a240add146943eb0492d9929c6c92174b6 (diff)
merge revision(s) e02bd0e7: [Backport #15608]
Don't display singleton class in Method#inspect unless method defined there Previously, if an object has a singleton class, and you call Object#method on the object, the resulting string would include the object's singleton class, even though the method was not defined in the singleton class. Change this so the we only show the singleton class if the method is defined in the singleton class. Fixes [Bug #15608] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_6@67902 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--proc.c9
-rw-r--r--spec/ruby/core/method/shared/to_s.rb18
-rw-r--r--test/ruby/test_method.rb8
-rw-r--r--version.h2
4 files changed, 35 insertions, 2 deletions
diff --git a/proc.c b/proc.c
index dc827c467f..caebee4466 100644
--- a/proc.c
+++ b/proc.c
@@ -2635,7 +2635,8 @@ method_inspect(VALUE method)
str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
OBJ_INFECT_RAW(str, method);
- mklass = data->klass;
+ mklass = data->iclass;
+ if (!mklass) mklass = data->klass;
if (data->me->def->type == VM_METHOD_TYPE_ALIAS) {
defined_class = data->me->def->body.alias.original_me->owner;
@@ -2667,6 +2668,12 @@ method_inspect(VALUE method)
}
}
else {
+ mklass = data->klass;
+ if (FL_TEST(mklass, FL_SINGLETON)) {
+ do {
+ mklass = RCLASS_SUPER(mklass);
+ } while (RB_TYPE_P(mklass, T_ICLASS));
+ }
rb_str_buf_append(str, rb_inspect(mklass));
if (defined_class != mklass) {
rb_str_catf(str, "(% "PRIsVALUE")", defined_class);
diff --git a/spec/ruby/core/method/shared/to_s.rb b/spec/ruby/core/method/shared/to_s.rb
index 373398a785..7666322936 100644
--- a/spec/ruby/core/method/shared/to_s.rb
+++ b/spec/ruby/core/method/shared/to_s.rb
@@ -31,4 +31,22 @@ describe :method_to_s, shared: true do
it "returns a String containing the Module the method is referenced from" do
@string.should =~ /MethodSpecs::MySub/
end
+
+ ruby_version_is '2.8' do
+ it "returns a String containing the Module containing the method if object has a singleton class but method is not defined in the singleton class" do
+ obj = MethodSpecs::MySub.new
+ obj.singleton_class
+ @m = obj.method(:bar)
+ @string = @m.send(@method).sub(/0x\w+/, '0xXXXXXX')
+ @string.should =~ /\A#<Method: MethodSpecs::MySub\(MethodSpecs::MyMod\)#bar\(\) /
+ end
+ end
+
+ it "returns a String containing the singleton class if method is defined in the singleton class" do
+ obj = MethodSpecs::MySub.new
+ def obj.bar; end
+ @m = obj.method(:bar)
+ @string = @m.send(@method).sub(/0x\w+/, '0xXXXXXX')
+ @string.should =~ /\A#<Method: #<MethodSpecs::MySub:0xXXXXXX>\.bar/
+ end
end
diff --git a/test/ruby/test_method.rb b/test/ruby/test_method.rb
index 3a7186584a..2d615ca53f 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -458,6 +458,14 @@ class TestMethod < Test::Unit::TestCase
m.taint
assert_predicate(m.inspect, :tainted?, "inspect result should be infected")
+
+ bug15608 = '[ruby-core:91570] [Bug #15608]'
+ c4 = Class.new(c)
+ c4.class_eval { alias bar foo }
+ o = c4.new
+ o.singleton_class
+ m4 = o.method(:bar)
+ assert_equal("#<Method: #{c4.inspect}(#{c.inspect})#bar(foo)>", m4.inspect, bug15608)
end
def test_callee_top_level
diff --git a/version.h b/version.h
index ed7f10b539..792d353ccb 100644
--- a/version.h
+++ b/version.h
@@ -1,6 +1,6 @@
#define RUBY_VERSION "2.6.7"
#define RUBY_RELEASE_DATE "2021-02-28"
-#define RUBY_PATCHLEVEL 161
+#define RUBY_PATCHLEVEL 162
#define RUBY_RELEASE_YEAR 2021
#define RUBY_RELEASE_MONTH 2