Exception#causeを使用したRubyのネストされたエラー
Rubyでは、別の種類の例外をレスキューして例外を発生させ、再発生させるのが一般的なパターンです。 ActionViewは、この非常に明白な例の1つです。 TracePointに関する以前のブログ投稿で述べたように、ActionViewはテンプレートで発生した例外をすべて飲み込み、ActionView::TemplateError
として再発生させます。 。
時々これは十分ではありません。問題の解決に役立つデータが含まれているため、元の例外が本当に必要です。幸い、Ruby 2.1では、Exception#causeメソッドを使用してそれを実行できます。
それが実際にどのように機能するか見てみましょう。ここでは、NoMethodError
を発生させます 、すぐにそれを飲み込み、RuntimeError
を発生させます 。次に、RuntimeError
をキャッチします #causeを使用して、元のNoMethodError
を取得します 。
def fail_and_reraise
raise NoMethodError
rescue
raise RuntimeError
end
begin
fail_and_reraise
rescue => e
puts "#{ e } caused by #{ e.cause }"
end
#causeメソッドは、実際には元の例外オブジェクトを返します。つまり、元の例外の一部であった任意のメタデータにアクセスできます。元のバックトレースも取得できます。
class EatingError < StandardError
attr_reader :food
def initialize(food)
@food = food
end
end
def fail_and_reraise
raise EatingError.new("soup")
rescue
raise RuntimeError
end
begin
fail_and_reraise
rescue => e
puts "#{ e } caused by #{ e.cause } while eating #{ e.cause.food }"
puts e.cause.backtrace.first
end
無限にそしてそれを超えて!
上記の例は1レベルの深さしかありませんが、Rubyのネストされた例外は任意の数のレベルを持つことができます。 4つのレベルのうち3つ以上の深さまで進む必要があるとしたら、私は驚きます。
...しかし、楽しみのために、100レベルの深いネストされた例外を作成してみようと思いました。これはばかげた小さなコードであり、本番環境でそのようなものが見られないことを願っています。
def recursively_raise(c=0)
raise "Level #{ c }"
rescue => e
if c < 100
recursively_raise(c + 1)
else
recursively_print(e)
end
end
def recursively_print(e)
if e
puts e
recursively_print(e.cause)
end
end
recursively_raise()
# ... Prints the following:
# Level 100
# Level 99
# Level 98
# etc.
-
TCmallocを使用したRubyのメモリ割り当てのプロファイリング
Rubyではメモリ割り当てはどのように機能しますか? Rubyはページと呼ばれるチャンクでメモリを取得し、新しいオブジェクトはここに保存されます。 次に… これらのページがいっぱいになると、より多くのメモリが必要になります。 Rubyは、mallocを使用してオペレーティングシステムからより多くのメモリを要求します 機能。 このmalloc 関数はオペレーティングシステム自体の一部ですが、使用できる代替の実装があります。 それらの実装の1つは、Googleのtcmallocです。 TCmallocはGoogleパフォーマンスツールスイートの一部です。 これらのツールを使用し
-
Rubyでパーサーを構築する方法
構文解析は、一連の文字列を理解し、それらを理解できるものに変換する技術です。正規表現を使用することもできますが、必ずしもその仕事に適しているとは限りません。 たとえば、HTMLを正規表現で解析することはおそらく良い考えではないことは一般的な知識です。 Rubyには、この作業を実行できるnokogiriがありますが、独自のパーサーを作成することで多くのことを学ぶことができます。始めましょう! Rubyでの解析 パーサーの中核はStringScannerです クラス。 このクラスは、文字列のコピーと位置ポインタを保持します。ポインタを使用すると、特定のトークンを検索するために文字列をトラバ