📑

【bugs.ruby Advent Calender】例外が発生するまで rescue のクラスが参照されない【6日目】

2024/12/06に公開

bugs.ruby Advent Calender 6日目の記事です。

これはなに

今年1年間通してみてきた bugs.ruby のチケットの中から気になったものを1つずつ取り上げていく Advent Calender です。
取り上げるチケットは基本的にこのブログで取り上げたものになります。
記事のまとめは ここを参照 してください。

例外が発生するまで rescue のクラスが参照されない

rescue Hge => e のように rescue 句でクラスを参照しているときに Hoge クラスは『例外が発生するまで』評価されません。
なので次のようなコードを実行したときに Hoge クラスが定義されていなくても例外が発生していないのであればエラーにならずに実行されます。

begin
  # ここで例外が発生されなければ Hoge は評価されずに定義されていなくてもエラーにならない
rescue Hoge => e
end

逆にいうと次のように例外が発生する場合は Hoge が見つからずに NameError になります。

begin
  raise "foo"
rescue Hoge => e
end
__END__
output:
test.rb:3:in `rescue in <main>': uninitialized constant Hoge (NameError)

rescue Hoge => e
       ^^^^
	from test.rb:1:in `<main>'
test.rb:2:in `<main>': foo (RuntimeError)

このチケットは rescue 句のクラスを実行前に読み込むようにする提案になります。
モチベーションとしては例えば rescue 句で定義していたクラスが typo などで間違っていると例外が発生するまで気づくことができない、みたいなところがあるみたいですね。

begin
  # rescue 句のクラス名が typo していても例外が発生しないと気づけない…
rescue StandradError => e
end

当たり前ではあるんですが Ruby は実行するまでコードは評価されないこういう挙動になるんですよねー。
例えば if 文とかでも同様になります。

if false
  # ここの処理が実行されない限りは Hoge は評価されない
  Hoge
end

これはそれはそうなんですが rescue 句でもそうなるとは今まで意識したことがなくて結構びっくりしましたね。
Ruby 側で事前にエラー検知できると便利かなーと思いつつ、こういう検知は構文解析ツールで対応するとよい、みたいな話もあるみたいですね。

関連

GitHubで編集を提案

Discussion