[前][次][番号順一覧][スレッド一覧]

ruby-changes:60401

From: Jeremy <ko1@a...>
Date: Sat, 14 Mar 2020 20:28:14 +0900 (JST)
Subject: [ruby-changes:60401] 0d24fb774d (ruby_2_7): Don't display singleton class in Method#inspect unless method defined there

https://git.ruby-lang.org/ruby.git/commit/?id=0d24fb774d

From 0d24fb774d84d4a99454ce10fd343da00049a588 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Mon, 9 Mar 2020 07:57:16 -0700
Subject: 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]

(cherry picked from commit e02bd0e713ef920e6d12c27f16548f48ec5c2cf0)

diff --git a/proc.c b/proc.c
index 01890b1..deffe1f 100644
--- a/proc.c
+++ b/proc.c
@@ -2804,7 +2804,8 @@ method_inspect(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L2804
     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.
@@ -2844,6 +2845,12 @@ method_inspect(VALUE method) https://github.com/ruby/ruby/blob/trunk/proc.c#L2845
 	}
     }
     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 373398a..7666322 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 https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/method/shared/to_s.rb#L31
   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 bb506f1..6ad9620 100644
--- a/test/ruby/test_method.rb
+++ b/test/ruby/test_method.rb
@@ -459,6 +459,14 @@ class TestMethod < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_method.rb#L459
     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
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]