Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

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.

  1. TCmallocを使用したRubyのメモリ割り当てのプロファイリング

    Rubyではメモリ割り当てはどのように機能しますか? Rubyはページと呼ばれるチャンクでメモリを取得し、新しいオブジェクトはここに保存されます。 次に… これらのページがいっぱいになると、より多くのメモリが必要になります。 Rubyは、mallocを使用してオペレーティングシステムからより多くのメモリを要求します 機能。 このmalloc 関数はオペレーティングシステム自体の一部ですが、使用できる代替の実装があります。 それらの実装の1つは、Googleのtcmallocです。 TCmallocはGoogleパフォーマンスツールスイートの一部です。 これらのツールを使用し

  2. Rubyでパーサーを構築する方法

    構文解析は、一連の文字列を理解し、それらを理解できるものに変換する技術です。正規表現を使用することもできますが、必ずしもその仕事に適しているとは限りません。 たとえば、HTMLを正規表現で解析することはおそらく良い考えではないことは一般的な知識です。 Rubyには、この作業を実行できるnokogiriがありますが、独自のパーサーを作成することで多くのことを学ぶことができます。始めましょう! Rubyでの解析 パーサーの中核はStringScannerです クラス。 このクラスは、文字列のコピーと位置ポインタを保持します。ポインタを使用すると、特定のトークンを検索するために文字列をトラバ