💡
[Feature #21543] ArgumentError のバックトレースをわかりやすくするチケット
[Feature #21543] Point ArgumentError to the call site
- 次のように
ArgumentErrorが発生すると
def foo(x, y)
end
foo(1)
- 以下のように『
fooメソッドの呼び出し先』がバックトレースの先頭としてエラーメッセージが出力される
$ ruby test.rb
test.rb:1:in `foo': wrong number of arguments (given 1, expected 2) (ArgumentError)
from test.rb:4:in `<main>'
- これを次のように『
fooメソッド呼び出し元』がバックトレースの先頭として表示されるようにしたいという旨のチケット
# こうなってほしい
$ ruby test.rb
test.rb:4:in `<main>': wrong number of arguments (given 1, expected 2) (ArgumentError)
for `foo' at test.rb:1
- モチベーションとしてはこういう引数が異なるエラーを修正する場合は『呼び出し元』である
foo(1)をfoo(1, 2)のように修正することが殆どで『呼び出し先』を修正すること殆どない - なので『呼び出し元』を見てから『呼び出し先』を確認する、みたいなフローになる
- しかし、バックトレースが『呼び出し先 -> 呼び出し元』の順になっているのでこれを『実際のデバッグフローに寄せたい』みたいなところみたいですね
- あんまり気にはしてなかったんですが確かに、って感じですね
- もう少しバックトレースが長い例
class TestClass
def foo(x, y)
end
def bar
foo(1)
end
def main
bar
end
end
TestClass.new.main
# 提案された内容
$ ruby test.rb
test.rb:6:in 'TestClass#bar': wrong number of arguments (given 1, expected 2) (ArgumentError)
for TestClass#foo at test.rb:2
from test.rb:10:in 'TestClass#main'
from test.rb:14:in '<main>'
# 現状の出力
$ ruby test.rb
test.rb:2:in 'foo': wrong number of arguments (given 1, expected 2) (ArgumentError)
from test.rb:6:in 'TestClass#bar'
from test.rb:10:in 'TestClass#main'
from test.rb:14:in '<main>'
- そもそもなんですがバックトレースとしてはエラーになった起点(ここでいう
foo(1)の呼び出し元)からスタートしてほしい気はするので提案された内容のほうが自然な気がしますねえ - ただ、次のように
forの部分だけ見るとバックトレースの順番としておかしい、みたいなコメントもされている
test.rb:6:in 'TestClass#bar': wrong number of arguments (given 1, expected 2) (ArgumentError)
↓の部分は実際の呼び出し順序とあっていない
for TestClass#foo at test.rb:2
from test.rb:10:in 'TestClass#main'
from test.rb:14:in '<main>'
- これなんですが最終的には Ruby 本体で対応するのではなくて
error_highlightで次のように表示するようになったみたい
# test.rb
def foo(x, y)
end
def bar
foo(1)
end
def baz
bar
end
baz
$ ruby test.rb
test.rb:2:in 'Object#foo': wrong number of arguments (given 1, expected 2) (ArgumentError)
caller: test.rb:6
| foo(1)
^^^
callee: test.rb:2
| def foo(x, y)
^^^
from test.rb:6:in 'Object#bar'
from test.rb:10:in 'Object#baz'
from test.rb:13:in '<main>'
- これはわかりやすいですねー
- エラーメッセージ関連をもっとわかりやすくしたいモチベーションはあるのでこのあたりはいろいろと参考にしたい
Discussion