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]
(cherry picked from commit e02bd0e713)
			
			
This commit is contained in:
		
							parent
							
								
									eabf35a5d2
								
							
						
					
					
						commit
						0d24fb774d
					
				
					 3 changed files with 34 additions and 1 deletions
				
			
		
							
								
								
									
										9
									
								
								proc.c
									
										
									
									
									
								
							
							
						
						
									
										9
									
								
								proc.c
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -2804,7 +2804,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.
 | 
			
		||||
| 
						 | 
				
			
			@ -2844,6 +2845,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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -459,6 +459,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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue