🙄
[Feature #21279] NameErrorやNoMethodErrorをrescueでキャッチしないようにするチケット
[Feature #21279] Bare "rescue" should not rescue NameError
-
NameErrorやNoMethodErrorはrescueでキャッチすべきではない、という内容のチケット - 例えば次のような
NameErrorが発生するとrescueで例外をキャッチすることができます- これは
NameErrorがStandardErrorを継承しておりrescueではクラスが指定されなかった場合はStandardErrorを継承しているクラスをキャッチするような挙動になっているため - また
NomenclatureはNameErrorのサブクラス
- これは
begin
DoesNotExist
rescue => e
p e # => #<NameError: uninitialized constant DoesNotExist>
end
-
NameErrorやNoMethodErrorは通常タイプミスなどで発生し、実行時には回復することができないのでSyntaxErrorと同様のエラーにするべき、みたいなのがモチベーションみたいですね - 対応としては
NameErrorの親クラスをStandardErrorにしない、みたいな対応を想定しているみたいです - チケットのコメントでは歴史的な話が書かれているんですが Ruby 1.6 〜 1.8 ではもともと
NameErrorはExceptionのサブクラスだったんですがそのあとにStandardErrorに移動した背景があるみたいです- が、なぜ
StandardErrorのサブクラスになったのかは明確にわからないとのこと - https://bugs.ruby-lang.org/issues/21279#note-2
-
d = nilの場合でもd.to_f rescue 0.0を動作するようにしたかった話はあったみたい
- が、なぜ
- これ、言いたいことはわからなくもないんですが
NameErrorが発生するのは実行時になるので『エラーが発生してもとりあえずプログラムは止まってほしくない』みたいな場合にはカバーできない気がするんですよねえ- あと互換性的に
NameError / NoMethodErrorを考慮してないrescueがほとんどだと思うので既存のコードはかなり壊れそう…
- あと互換性的に
- 最終的には歴史的な制約や互換性を考えて、現状のまま維持することになりました
- ここら辺、ユーザ側で制御できるとよい気もするんですが継承リストをあとから変更することはできないのでなかなかむずかしそうですねえ
Discussion