Prawn: Prawn :: Documentでinspectを呼び出すのは非常に遅い

作成日 2018年05月17日  ·  5コメント  ·  ソース: prawnpdf/prawn

やあ! 奇妙なバグに遭遇しました。 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を使用しています。

最も参考になるコメント

さて、私にとって最も簡単な修正は、 inspectto_s呼び出せるようにする単純なパッチです。 Rubyソースコードを見ると、 inspectは、それ自体にインスタンス変数がない場合にto_s inspect呼び出すため、 #<Prawn::Document:0x00007fa9c0e884d0>ようなものを出力し、無限の再帰を引き起こすインスタンス変数を省略します。 ( inspectは、ivar自体がある場合、そのivarでinspectを呼び出すため)。

class Prawn::Document
  alias_method :inspect, :to_s
end

このパッチは、適切な動作を提供しながら症状を防ぎますが、さらに良いアプローチは、どの特定のivar(または実際にはそのクラス)が問題を引き起こしているかを判断し、代わりにそのクラスにパッチを適用することです。

全てのコメント5件

一般的に、そうすべきではありません。 ドキュメントには大量の状態が含まれていますが、ほとんどが内部のものであるため、プレゼンテーションはあまり有用な情報を提供しません。 有用な代替品がないため、デフォルトのRuby実装を残しました。

絶対に、それは完全に理にかなっています。 ただし、問題は、(私の場合)Rubyが例外メッセージを出力しようとするためにPrawnで開発するときに発生したNoMethodErrorがハングし、 NameErrorとそのサブクラスがそのメッセージを生成するときに内部でinspectを呼び出すことです。

はい、問題があります。 解決策を提案することを歓迎します。

さて、私にとって最も簡単な修正は、 inspectto_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'`のどこかにあります。

このページは役に立ちましたか?
0 / 5 - 0 評価