やあ! 奇妙なバグに遭遇しました。 Prawn::Document
インスタンスでinspect
を呼び出すと、大量のメモリとCPUを消費しながら、結果が生成されるまでに数分かかります。 これは、たとえばNoMethodError
が発生し、例外メッセージでドキュメントオブジェクトを検査する場合に煩わしいことがあります。
簡単なグーグルは他のプロジェクトでいくつかの同様の問題を見つけました:
https://github.com/rails/rails/issues/1525#issuecomment -4075591
https://github.com/rom-rb/rom-repository/pull/65
Ruby2.5.0p0を使用しています。
一般的に、そうすべきではありません。 ドキュメントには大量の状態が含まれていますが、ほとんどが内部のものであるため、プレゼンテーションはあまり有用な情報を提供しません。 有用な代替品がないため、デフォルトのRuby実装を残しました。
絶対に、それは完全に理にかなっています。 ただし、問題は、(私の場合)Rubyが例外メッセージを出力しようとするためにPrawnで開発するときに発生したNoMethodError
がハングし、 NameError
とそのサブクラスがそのメッセージを生成するときに内部でinspectを呼び出すことです。
はい、問題があります。 解決策を提案することを歓迎します。
さて、私にとって最も簡単な修正は、 inspect
がto_s
呼び出せるようにする単純なパッチです。 Rubyソースコードを見ると、 inspect
は、それ自体にインスタンス変数がない場合にto_s
inspect
呼び出すため、 #<Prawn::Document:0x00007fa9c0e884d0>
ようなものを出力し、無限の再帰を引き起こすインスタンス変数を省略します。 ( inspect
は、ivar自体がある場合、そのivarでinspect
を呼び出すため)。
class Prawn::Document
alias_method :inspect, :to_s
end
このパッチは、適切な動作を提供しながら症状を防ぎますが、さらに良いアプローチは、どの特定のivar(または実際にはそのクラス)が問題を引き起こしているかを判断し、代わりにそのクラスにパッチを適用することです。
また、Prawn :: DocumentのインスタンスでNoMethodError
を報告しようとしているときに、Rubyが完全にハングすることによってもこれに遭遇しました
何が原因であるかを理解するのに何時間もかかりました、そしてその知識で私はグーグルでこれに遭遇しました。
次に、 to_s
基づいて最も単純なinspect
出力を提供するか、または最小限の状態を提供するという提案を2番目に示します。
私の調査によると、問題はpdf-core-0.9.0/lib/pdf/core/stream.rb:99:in
inspect'`のどこかにあります。
最も参考になるコメント
さて、私にとって最も簡単な修正は、
inspect
がto_s
呼び出せるようにする単純なパッチです。 Rubyソースコードを見ると、inspect
は、それ自体にインスタンス変数がない場合にto_s
inspect
呼び出すため、#<Prawn::Document:0x00007fa9c0e884d0>
ようなものを出力し、無限の再帰を引き起こすインスタンス変数を省略します。 (inspect
は、ivar自体がある場合、そのivarでinspect
を呼び出すため)。このパッチは、適切な動作を提供しながら症状を防ぎますが、さらに良いアプローチは、どの特定のivar(または実際にはそのクラス)が問題を引き起こしているかを判断し、代わりにそのクラスにパッチを適用することです。