Tech Racho エンジニアの「?」を「!」に。
  • Ruby / Rails関連

Ruby 3.1: error_highlight gemが追加された(翻訳)

概要

元サイトの許諾を得て翻訳・公開いたします。

Ruby 3.1: error_highlight gemが追加された(翻訳)

プログラミング言語で例外やエラーが発生すると、エラーのスタックトレースを扱います。スタックトレースは、エラーの発生場所を整った書式で示し、プログラムのサブルーチンに関する情報を提供します。

Rubyを使っていると、さまざまな場所でエラーや例外が発生することに気づきます。例を見てみましょう。

# test.rb
class Addition
  attr_reader :num1, :num2

  def initialize(num1, num2)
    @num1 = num1
    @num2 = num2
  end

  def result
    num1 + num2
  end
end

Addition.new(1, "2").result
Terminal$ ruby test.rb
test.rb:10:in `+': String can't be coerced into Integer (TypeError)
    from test.rb:10:in `result'
    from test.rb:14:in `<main>'

irbでも同様に、エラーが発生した行番号が示されます。

(irb):10:in `+': String can't be coerced into Integer (TypeError)

改修前

上のエラー程度なら、どこが間違っているかは割とすぐにわかるでしょう。そこで、とあるAPIレスポンスをパースして、ネストしたJSONオブジェクトからユーザーデータをフェッチする場合の例を見てみましょう。

# test.rb
class ParseResponse
  attr_reader :data

  def initialize(data)
    @data = data
  end

  def user_name
    data[:result].first[:first_name]
  end
end

data = { result: {} }
ParseResponse.new(data).user_name
Terminal$ ruby test.rb
Traceback (most recent call last):
    1: from test.rb:14:in `<main>'
test.rb:9:in `user_name': undefined method `[]' for nil:NilClass (NoMethodError)

このundefined method [] for nil:NilClassエラーでは、data[:result]nilなのか、それともdata[:result].firstnilなのかがわかりません。もっと複雑にネストしたJSONレスポンスだったら、どのパラメータがnilなのかを特定するだけで一苦労です。

改修後

ruby/error_highlight - GitHub

Ruby 3.1にerror_highlight gemが同梱され、Rubyのプロセスが起動するときにrequireされるようになりました。このgemを利用するのに追加のセットアップは不要です。

上のコードをRuby 3.1.0で動かすと、データがnilになっている箇所が行内のどこにあるかがわかりやすく表示されます。

$ ruby test.rb
test.rb:9:in `user_name': undefined method `[]' for nil:NilClass (NoMethodError)

    data[:result].first[:first_name]
                       ^^^^^^^^^^^^^
    from test.rb:14:in `<main>'

.firstの ^^^^^^^^^^^^^で示された 部分がnilになっています。

空のdataを渡すと、以下のように.firstの部分がエラーとしてハイライトされます。

$ ruby test.rb
test.rb:9:in `user_name': undefined method `first' for nil:NilClass (NoMethodError)

    data[:result].first[:first_name]
                 ^^^^^^
    from test.rb:14:in `<main>'

ハイライト形式をカスタマイズする

error_highlight gemには独自のフォーマッタを追加する機能が提供されています。追加するには、以下のように#message_forメソッドをオーバーライドしてErrorHighlight.formatter=に代入する必要があります。

formatter = Object.new
def formatter.message_for(spot)
  marker = " " * spot[:first_column] + "*" * (spot[:last_column] - spot[:first_column] - 1)

  "\n\n#{ spot[:snippet] }#{ marker }"
end

ErrorHighlight.formatter = formatter

上のフォーマッタを適用すると、エラーハイライトが^から*に変更されます。

$ ruby test.rb
test.rb:9:in `user_name': undefined method `first' for nil:NilClass (NoMethodError)

    data[:result].first[:first_name]
                 ******
    from test.rb:14:in `<main>'

error_highlightを無効にする

rubyコマンドに--disable-error_highlightを渡すと、error_highlight gemを無効にできます。

$ ruby --disable-error_highlight test.rb
test.rb:9:in `user_name': undefined method `[]' for nil:NilClass (NoMethodError)
    from test.rb:14:in `<main>'

原注: error_highlight gemはMRIでのみ動作します。また、Rubyバージョンは3.1以上が必須です。

関連記事

Rais 7のbyebugがruby/debugに置き換わる(翻訳)


CONTACT

TechRachoでは、パートナーシップをご検討いただける方からの
ご連絡をお待ちしております。ぜひお気軽にご意見・ご相談ください。