Bug #22197
openBacktraces show methods which do not exist
Description
class Parent
def original
puts caller_locations(0), nil
end
end
class Child < Parent
alias_method :alias, :original
end
Child.new.alias
module Original
def original
puts caller_locations(0)
end
end
class A
define_method(:a, Original.instance_method(:original))
end
A.new.a
gives:
$ ruby -v backtrace_alias.rb
ruby 4.0.3 (2026-04-21 revision 85ddef263a) +PRISM [arm64-darwin25]
backtrace_alias.rb:3:in 'Child#original'
backtrace_alias.rb:11:in '<main>'
backtrace_alias.rb:15:in 'A#original'
backtrace_alias.rb:23:in '<main>'
But this seems clearly incorrect:
- there is no
Child#original, there is onlyParent#originalandChild#alias. - there is no
A#original, there is onlyOriginal#originalandA#a.
This behavior exists since Ruby 3.4 which added the module name in backtraces (#19117).
So the issue is that backtraces show the "original method name from the definition" with the "method owner of the actually-called method".
It should be consistent to avoid showing methods which don't exist.
And it should be the original method from the definition, because we show the file and line of that, so we should also show the original name (already the case) and the original module (not the case yet, the bug).
FWIW TruffleRuby already behaves like that:
$ truffleruby 34.0.1 (2026-04-26), like ruby 3.4.9, Oracle GraalVM Native [arm64-darwin23]
backtrace_alias.rb:3:in 'Parent#original'
backtrace_alias.rb:11:in '<main>'
backtrace_alias.rb:15:in 'Original#original'
backtrace_alias.rb:23:in '<main>'
In #19117 there was some discussion about this, notably:
https://bugs.ruby-lang.org/issues/19117#note-17
@byroot (Jean Boussier)
My suggestion is for the owner. Simply put because it matches the path and other existing method representations.
But actually the owner isn't that, what is described here is the original module of the method definition, same as the expected from this issue.
https://bugs.ruby-lang.org/issues/19117#note-18
@Eregon (Benoit Daloze)
It must be the owner, anything else would be very confusing.
I believe nobody wants String#then (there is no such method), they want to see Kernel#then.
Where I was wrong about owner being the only thing. I was also expressing we should show where the method is defined, but I overlooked the "originally" part (aliases, define_method, etc).
Also CC @mame (Yusuke Endoh) who implemented the change.
I think this is worth fixing for Ruby 4.1 (not sure if worth backporting).