Add specs for Method#original_name and #inspect with Kernel methods#1356
Conversation
Fix Method#original_name and #inspect when two methods share a wrapper (like is_a?/kind_of?) Introduce sourceName on DynamicMethod to preserve a method's source name when methods share a single underlying wrapper. Set it in RubyModule when binding, walk the alias chain in AliasMethod#getOldName to reach it, and consult it from Method#original_name and #inspect so both report the correct source name instead of whichever name happened to live on the wrapper. Covered by new specs in ruby/spec#1356 (ruby/spec#1356).
Fix Method#original_name and #inspect when two methods share a wrapper (like is_a?/kind_of?) Introduce sourceName on DynamicMethod to preserve a method's source name when methods share a single underlying wrapper. Set it in RubyModule when binding, walk the alias chain in AliasMethod#getOldName to reach it, and consult it from Method#original_name and #inspect so both report the correct source name instead of whichever name happened to live on the wrapper. Covered by new specs in ruby/spec#1356 (ruby/spec#1356).
headius
left a comment
There was a problem hiding this comment.
This looks fine to me and fills a gap in specs.
headius
left a comment
There was a problem hiding this comment.
Actually, two small changes here would clean this up and we can merge.
b1a7c91 to
03ed56a
Compare
| def original_method; end | ||
| alias_method :renamed_method, :original_method | ||
| end | ||
| klass.new.method(:renamed_method).send(@method).should =~ /#renamed_method\(original_method\)/ |
There was a problem hiding this comment.
| klass.new.method(:renamed_method).send(@method).should =~ /#renamed_method\(original_method\)/ | |
| klass.new.method(:renamed_method).send(@method).should.include? '#renamed_method(original_method)' |
|
|
||
| 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\?\)/ |
There was a problem hiding this comment.
Same, .should.include? is much easier to read by avoiding escaping.
Same below
| Object.new.method(:is_a?).send(@method).should_not =~ /\(kind_of\?\)/ | ||
| Object.new.method(:kind_of?).send(@method).should_not =~ /\(is_a\?\)/ |
|
|
||
| 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?)) |
There was a problem hiding this comment.
I think it'd be good to give this one another name for clarity and to make it more interesting
| klass = Class.new { define_method(:is_a?, ::Kernel.instance_method(:is_a?)) } | ||
| klass.new.method(:is_a?).original_name.should == :is_a? |
There was a problem hiding this comment.
Give the new method another name otherwise this doesn't test anything, same below
|
|
||
| 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?)) |
There was a problem hiding this comment.
Same, this should have another name
| UnboundMethodSpecs::A.instance_method(:baz).send(@method).should.start_with? "#<UnboundMethod: UnboundMethodSpecs::A#baz" | ||
| end | ||
|
|
||
| it "shows the original name in parentheses for an aliased method" do |
There was a problem hiding this comment.
This duplication for UnboundMethod is not ideal. One way to fix it would be to use a separate shared spec describe, require it from both specs and pass a lambda as @object, for Method it's just be identity and for UnboundMethod it'd be -> meth { meth.unbind }.
This is a bigger/trickier change though so if you don't feel comfortable with it I think it's OK to keep the duplication in this PR.
There was a problem hiding this comment.
Thank you! That did make tests look much nicer.
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.
03ed56a to
5f21795
Compare
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.
Also documents inspect's behavior on aliased methods, which wasn't previously covered.
Continuing the work started in #1353 and adding specs that fail at least on JRuby. (the specs added in that PR now pass on JRuby master though!)