From b1a7c9101b275c3c0baff1724a8597550462f434 Mon Sep 17 00:00:00 2001 From: Sampo Kuokkanen Date: Mon, 11 May 2026 14:26:32 +0900 Subject: [PATCH] Add specs for Method#original_name and #inspect with Kernel methods Adds specs for Method#original_name and #inspect when define_method or alias is used with Kernel#is_a? / Kernel#kind_of? methods that can share an internal implementation in some Ruby implementations. Existing specs didn't catch when introspection leaked the shared internal name. --- core/method/original_name_spec.rb | 16 +++++++++++++++ core/method/shared/to_s.rb | 26 ++++++++++++++++++++++++ core/unboundmethod/original_name_spec.rb | 16 +++++++++++++++ core/unboundmethod/shared/to_s.rb | 26 ++++++++++++++++++++++++ 4 files changed, 84 insertions(+) diff --git a/core/method/original_name_spec.rb b/core/method/original_name_spec.rb index 8fec0e7c3..e4f55d6f0 100644 --- a/core/method/original_name_spec.rb +++ b/core/method/original_name_spec.rb @@ -40,4 +40,20 @@ klass.new.method(:renamed).original_name.should == :my_method klass.new.method(:aliased).original_name.should == :my_method end + + it "returns the source UnboundMethod's name for Kernel#is_a? and Kernel#kind_of?" do + klass = Class.new { define_method(:is_a?, ::Kernel.instance_method(:is_a?)) } + klass.new.method(:is_a?).original_name.should == :is_a? + + klass = Class.new { define_method(:kind_of?, ::Kernel.instance_method(:kind_of?)) } + klass.new.method(:kind_of?).original_name.should == :kind_of? + end + + it "preserves the source name when aliasing a define_method'd Kernel method" do + klass = Class.new do + define_method(:is_a?, ::Kernel.instance_method(:is_a?)) + alias_method :renamed_is_a?, :is_a? + end + klass.new.method(:renamed_is_a?).original_name.should == :is_a? + end end diff --git a/core/method/shared/to_s.rb b/core/method/shared/to_s.rb index bfb58e689..c1e9ef8e4 100644 --- a/core/method/shared/to_s.rb +++ b/core/method/shared/to_s.rb @@ -78,4 +78,30 @@ def obj.bar; end it "shows the metaclass and the owner for a Module instance method retrieved from a class" do String.method(:include).inspect.should.start_with?("#(Module)#include") end + + it "shows the original name in parentheses for an aliased method" do + klass = Class.new do + def original_method; end + alias_method :renamed_is_a?, :original_method + end + klass.new.method(:renamed_is_a?).send(@method).should =~ /#renamed_is_a\?\(original_method\)/ + end + + it "shows the source UnboundMethod's name in parentheses for a define_method'd method" do + klass = Class.new { define_method(:renamed_is_a?, ::Kernel.instance_method(:is_a?)) } + klass.new.method(:renamed_is_a?).send(@method).should =~ /#renamed_is_a\?\(is_a\?\)/ + end + + it "does not annotate a directly looked-up Kernel method with a shared internal name" do + Object.new.method(:is_a?).send(@method).should_not =~ /\(kind_of\?\)/ + Object.new.method(:kind_of?).send(@method).should_not =~ /\(is_a\?\)/ + end + + it "shows the source name when aliasing a define_method'd Kernel method" do + klass = Class.new do + define_method(:is_a?, ::Kernel.instance_method(:is_a?)) + alias_method :renamed_is_a?, :is_a? + end + klass.new.method(:renamed_is_a?).send(@method).should =~ /#renamed_is_a\?\(is_a\?\)/ + end end diff --git a/core/unboundmethod/original_name_spec.rb b/core/unboundmethod/original_name_spec.rb index fa9a6fcc6..358871f8a 100644 --- a/core/unboundmethod/original_name_spec.rb +++ b/core/unboundmethod/original_name_spec.rb @@ -40,4 +40,20 @@ klass.instance_method(:renamed).original_name.should == :my_method klass.instance_method(:aliased).original_name.should == :my_method end + + it "returns the source UnboundMethod's name for Kernel#is_a? and Kernel#kind_of?" do + klass = Class.new { define_method(:is_a?, ::Kernel.instance_method(:is_a?)) } + klass.instance_method(:is_a?).original_name.should == :is_a? + + klass = Class.new { define_method(:kind_of?, ::Kernel.instance_method(:kind_of?)) } + klass.instance_method(:kind_of?).original_name.should == :kind_of? + end + + it "preserves the source name when aliasing a define_method'd Kernel method" do + klass = Class.new do + define_method(:is_a?, ::Kernel.instance_method(:is_a?)) + alias_method :renamed_is_a?, :is_a? + end + klass.instance_method(:renamed_is_a?).original_name.should == :is_a? + end end diff --git a/core/unboundmethod/shared/to_s.rb b/core/unboundmethod/shared/to_s.rb index 848c1eba2..dcaffeca8 100644 --- a/core/unboundmethod/shared/to_s.rb +++ b/core/unboundmethod/shared/to_s.rb @@ -30,4 +30,30 @@ it "does not show the defining module if it is the same as the origin" do UnboundMethodSpecs::A.instance_method(:baz).send(@method).should.start_with? "#