🐥
[Feature #19117] バックトレースでメソッド名が含まれるときに定義元の情報も含めるようにする提案
bugs.ruby のタイトルをそのまま Zenn のタイトルにすると文字数制限で入れきれない事が多いので日本語にしてみました。
[Feature #19117] Include the method owner in backtraces, not just the method name
- エラーとバックトレースの内容のメソッド名に『どのクラスで定義されているのか』の情報を含めるようにする提案
- 以下のコードを実行したときに
module Foo
class Bar
def inspect
1 + '1'
end
end
end
p Foo::Bar.new
- 以下のようなエラーが出力されるが
/tmp/foo.rb:4:in `+': String can't be coerced into Integer (TypeError)
from /tmp/foo.rb:4:in `inspect'
from /tmp/foo.rb:9:in `p'
from /tmp/foo.rb:9:in `<main>'
- 以下のように『どこで定義されているのか』を追加する提案
/tmp/foo.rb:4:in `Integer#+': String can't be coerced into Integer (TypeError)
from /tmp/foo.rb:4:in `Foo::Bar#inspect'
from /tmp/foo.rb:9:in `Kernel#p'
from /tmp/foo.rb:9:in `<main>'
- 普通に便利そう
- 懸念点としては
#inspect
をそのまま利用すると Rails では以下のような出力されれる可能性があるとコメントされている
app/models/organization.rb:458:in `Organization(id: integer, name: string, created_at: datetime, updated_at: datetime, ....and so on, 35 fields in total...)#inspect`
- 他にも特異クラスや無名クラスの場合にどうするのか、みたいな話もでていますね
- 他も以下のうような話とか
- 定義されているクラスなのか、呼び出したクラスなのか
- https://bugs.ruby-lang.org/issues/19117#note-16
class Foo
def inspect
raise "hmm"
end
end
class Bar < Foo
end
Bar.new.inspect
#/path/to/foo.rb:3:in `Foo#inspect': hmm (RuntimeError)
#or
#/path/to/foo.rb:3:in `Bar#inspect': hmm (RuntimeError)
- チケット自体は1年以上前につくられているんですが Ruy 3.2 のリリース直前に議論されていたぽいので暫く止まってたみたいですね
- いまは Ruby 3.4 に向けて開発しているみたいです
- 概ね肯定ぽいけどパフォーマンスどうなのか、みたいな議論がされている
- あとバッククオートについても言及されている
- 以下みたいにやや冗長なケースもありつつまあ普通に便利そうすねー
#before
from /opt/ruby/3.1/lib/ruby/gems/3.1.0/gems/activerecord-7.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:531:in 'with_multi_statements'
#after
from /opt/ruby/3.1/lib/ruby/gems/3.1.0/gems/activerecord-7.0.3/lib/active_record/connection_adapters/abstract/database_statements.rb:531:in 'ActiveRecord::ConnectionAdapters::DatabaseStatements#with_multi_statements'
Discussion