📑
【bugs.ruby Advent Calender】例外が発生するまで rescue のクラスが参照されない【6日目】
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 側で事前にエラー検知できると便利かなーと思いつつ、こういう検知は構文解析ツールで対応するとよい、みたいな話もあるみたいですね。
Discussion