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

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]
This commit is contained in:
Jeremy Evans 2020-03-09 07:57:16 -07:00 committed by GitHub
parent ecef163cf9
commit e02bd0e713
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
Notes: git 2020-03-09 23:57:39 +09:00
Merged: https://github.com/ruby/ruby/pull/2949

Merged-By: jeremyevans <code@jeremyevans.net>
3 changed files with 34 additions and 1 deletions

9
proc.c
View file

@ -2812,7 +2812,8 @@ method_inspect(VALUE method)
TypedData_Get_Struct(method, struct METHOD, &method_data_type, data);
str = rb_sprintf("#<% "PRIsVALUE": ", rb_obj_class(method));
mklass = data->klass;
mklass = data->iclass;
if (!mklass) mklass = data->klass;
if (RB_TYPE_P(mklass, T_ICLASS)) {
/* TODO: I'm not sure why mklass is T_ICLASS.
@ -2852,6 +2853,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);

View file

@ -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

View file

@ -465,6 +465,14 @@ class TestMethod < Test::Unit::TestCase
c3.class_eval { alias bar foo }
m3 = c3.new.method(:bar)
assert_equal("#<Method: #{c3.inspect}(#{c.inspect})#bar(foo)() #{__FILE__}:#{line_no}>", m3.inspect, bug7806)
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)() #{__FILE__}:#{line_no}>", m4.inspect, bug15608)
end
def test_callee_top_level