0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ruby クイズ:「通常のプログラムで発生する可能性の高い」例外だけど StandardError じゃないやつな〜んだ?

Posted at

Ruby 公式リファレンスの StandardError には,

通常のプログラムで発生する可能性の高い例外クラスを束ねるためのクラスです。

とある。
つまり,NameError, ArgumentError, TypeError, ZeroDivisionError, RuntimeError といった「よく出くわすやつ」はみ〜んな StandardError のサブクラスというわけだ。

いや,本当にそうなのか?
実は,通常のプログラムでよく発生する例外なのに StandardError のサブクラスになっていないやつがある。
それ,な〜んだ?

例外クラスの継承関係は
https://docs.ruby-lang.org/ja/3.4/library/_builtin.html#:~:text=%E4%BE%8B%E5%A4%96%E3%82%AF%E3%83%A9%E3%82%B9
で確認しよう。

見つけた?
LoadError がそれだ。
require するライブラリー名をタイポしたらこれが出る。
ときどき見るよね?

LoadError は ScriptError のサブクラスになっていて,StandardError のサブクラスにはなっていない。

だから,

begin
  require "hoge"
rescue StandardError
  puts "そんなライブラリー知らん"
end

と書いてもダメ。rescue LoadError としなければならない1

ScriptError のサブクラスには SyntaxError もある。
「こっちのほうが頻出では?」と思うかもしれないが,ちょっと位置付けが違う。
我々がふだんよく目にする SyntaxError は,書いたスクリプトに構文エラーがあって,実行が始まる前に起こるものだ。

だから

begin
  x =. 1
rescue SyntaxError
  puts "構文が間違っとる"
end

というスクリプトを実行しようとしても「構文が間違っとる」は表示されない。
スクリプトが構文的に間違っているので,実行すらされないのだ。

では,SyntaxError を捕捉するような機会はないのか?
ある。
こういう例だ

begin
  eval "x =. 1"
rescue SyntaxError
  puts "構文が間違っとる"
end

このスクリプト自体には構文上の問題はなく,実行される。
しかし,eval を実行するとき,与えられた文字列 "x =. 1" が Ruby のコードとして構文上の問題を抱えているので,SyntaxError が発生する。

  1. LoadError の捕捉はしばしば必要になる。xxx というライブラリーが無いときに代わりに yyy を読み込む,とか。gem のソースコードで LoadError を検索してみよう!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?