4.3 例外の生成と発生

4.1、4.2では標準ライブラリが発生させた例外を捕捉する方法を説明した。このページでは自分で例外を生成してその例外を発生させる(処理を中断させる)方法を説明する。

自分で例外を発生させる時には以下のように記述する。

# (1)
raise [例外オブジェクト]

# (2)
raise [例外オブジェクトの型], [メッセージ], [トラック情報]

# (3)
raise [例外オブジェクトの型], [メッセージ]

# (4)
raise [メッセージ]

一つひとつ順番に見ていこう。 まず(1)の書き方は単純に、例外オブジェクトを生成して発生させる方法である。それ以下の三つはこれを基本に書かれている。 (2)は、例外を発生させる時に一緒にオブジェクトを生成する方法だ。メッセージは4.2で説明した通り、例外を捕捉して表示したときに表示される文字列である。トラック情報というのは例外が発生した実行位置のことだが、この実行位置というのはコード上の位置ではなく、コンピュータが命令を読み込みに行ったスタック情報を指している。階層の低い情報なので、高度なプログラムを書かない限り必要になることはないだろう。 (3)は(2)からトラック情報を省略する方法で振る舞いは(2)とほぼ同じだ。 (4)は(3)からさらに例外オブジェクトの型を省略する方法である。この方法を使うと、自動的に例外オブジェクトの型はRuntimeErrorになる(Javaなど多くのプログラミング言語では例外オブジェクトの型にはExceptionという名前が付けられるが、Rubyでは慣例的にErrorという名前が付けられることが多い)。

では、4.1から通して見てきたテキストファイルをコピーする例で例外を発生させるように書き換えてみよう。

begin
    raise 'text/ directory has not found.' if exists_dir_of?('text') == false # raiseを追加

  input_file = open('text/input.txt', 'w+')
  output_file = open('text/output.txt', 'w')

rescue RuntimeError => e # RuntimeErrorに特定
    puts e
  Dir::mkdir('text')
  retry

else
  output_file.write("==Copy start==\n")
  output_file.write(input_file.read)
  output_file.write("==Copy end==\n")
  input_file.close
  output_file.close

ensure
  puts 'finish.'

end

exists_dir_of?(dir_name)メソッドはdir_nameという名前のディレクトがあればtrue、なければfalseを返す自作メソッドである(標準ライブラリのメゾッドにはない)。

上の例は思った通りに動いてくれるが、普通は例外処理はこのような使い方はしない。というのも、begin節内でraiseを定義して例外を捕捉するならば、if文で条件分岐すれば済むからだ。例外処理は普通、begin節の処理で使用するメソッド内に隠れた例外を捕捉するために使用する。実際に、上の例の様にraiseを書かなくても4.1、4.2の時点で例外は捕捉できていたので、ここでは無駄な例外を発生させていることになる。

results matching ""

    No results matching ""