From: "Eregon (Benoit Daloze) via ruby-core" Date: 2025-06-22T10:34:02+00:00 Subject: [ruby-core:122576] [Ruby Misc#20968] `Array#fetch_values` unexpected method name in stack trace Issue #20968 has been updated by Eregon (Benoit Daloze). @mame Here is an example bug due to this change, based on the `inject` case I mentioned in https://bugs.ruby-lang.org/issues/20968#note-6. I think this is strong enough to revert that change. ruby-master: ``` $ ruby -e '[1,2].inject(:tap)' -e:in '
': wrong number of arguments (given 1, expected 0) (ArgumentError) from -e:1:in 'Enumerable#inject' from -e:1:in '
' ``` This backtrace does not show `tap` is called, that's a bug, since the ArgumentError is from `Kernel#tap`. Instead, this backtrace pretends the ArgumentError comes from `-e:in '
'`, that is wrong and incorrect, `-e:in '
'` does not raise an exception itself, there is no `raise` in `
`. BTW, that location is missing a line number (`-e` instead of `-e:1`), that's another problem & inconsistency. I think no one wants this backtrace, it's wrong in many ways. With `ruby -e '[1,2].inject(:class)'` ruby-master gives the exact same backtrace, even though the exception originates from a different method (Kernel#class) but the backtrace completely hides this crucial information. 3.4.2: ``` $ ruby -e '[1,2].inject(:tap)' :89:in 'tap': wrong number of arguments (given 1, expected 0) (ArgumentError) from -e:1:in 'Enumerable#inject' from -e:1:in '
' ``` This is correct, it is clear that it is `tap` that raises the `ArgumentError`, and that `tap` is defined in `:89` and that `tap` is called by `inject`. I think most people would expect this backtrace. (nitpick: it would be nice if it would show `in 'Kernel#tap'` instead of `in 'tap'` but that is probably a separate improvement) This bug happens whenever a core method (whether defined in C or Ruby) calls another core method defined in Ruby, because the change here hides crucial information. See [this list](https://gist.github.com/eregon/912e6359e83781c5fa1c638d3768c526) of core methods defined in Ruby if you want to experiment more. --- FWIW, this is what it looks on TruffleRuby: ``` $ ruby -ve '[1,2].inject(:tap)' truffleruby 24.2.1, like ruby 3.3.7, Oracle GraalVM Native [x86_64-linux] core/kernel.rb:519:in `tap': wrong number of arguments (given 1, expected 0) (ArgumentError) from core/enumerable.rb:528:in `inject' from -e:1:in `
' ``` It's correct and similar to CRuby 3.4, except `Enumerable#inject` is also defined in Ruby. ---------------------------------------- Misc #20968: `Array#fetch_values` unexpected method name in stack trace https://bugs.ruby-lang.org/issues/20968#change-113811 * Author: koic (Koichi ITO) * Status: Closed ---------------------------------------- It seems that the current Ruby implementation is displaying unexpected method name in stack trace. ## Expected Similar to `Hash#fetch_values`, the method name `Array#fetch_values` is expected to be displayed in the stack trace. ```console $ ruby -e '{k: 42}.fetch_values(:unknown)' -e:1:in 'Hash#fetch_values': key not found: :unknown (KeyError) from -e:1:in '
' $ ruby -e '[1].fetch_values(42)' -e:1:in 'Array#fetch_values': index 42 outside of array bounds: -1...1 (IndexError) from -e:1:in '
' ``` ## Actual The stack trace displays the `Array#fetch` method, which user is not aware of, along with the `` stack trace. ```console $ ruby -e '[1].fetch_values(42)' :211:in 'Array#fetch': index 42 outside of array bounds: -1...1 (IndexError) from :211:in 'block in Array#fetch_values' from :211:in 'Array#map!' from :211:in 'Array#fetch_values' from -e:1:in '
' ``` It likely requires an approach such as implementing it in C, as suggested in https://github.com/ruby/ruby/pull/11555. -- https://bugs.ruby-lang.org/ ______________________________________________ ruby-core mailing list -- ruby-core@ml.ruby-lang.org To unsubscribe send an email to ruby-core-leave@ml.ruby-lang.org ruby-core info -- https://ml.ruby-lang.org/mailman3/lists/ruby-core.ml.ruby-lang.org/