けいじゅ@SHLジャパンです. 

松本氏のメイルに負けないくらい長いです(^^;;;

In [ruby-list :00385 ] the message: "[ruby-list:385] about exception
", on Aug/08 13:08(JST) matz / caelum.co.jp (Yukihiro Matsumoto) writes:

>1. system callから発生する例外
>
>  rubyはsystem callが負の値を返すと例外を発生するようになっ
>  ています.この時の $! の値は perror() の出力する文字列と同
>  じです.つまり,perror() で出力される文字列です.
>
>  これらはrubyのドキュメントには載っていませんが(いつか載せ
>  ます),<errno.h>を見ると載っています.

これに関しては, ruby でも errno が取り出せると嬉しいですね.

>2.なぜrubyの例外処理はああなのか
>  例外が発生した時にその対応としては以下のような場合が考えら
>  れます.
>   (1) その場でプログラムを中断する
>   (2) 例外の種類にかかわらず,なんらかの対応を行う
>   (3) 例外の種類毎に,それぞれ別の対応を行う

>  3の場合は変数 $! に例外情報が文字列で入っているので,それ
>  によって分岐する必要があります.また例外の種別以外に何らか
>  の情報が必要であれば,大域変数などを使ってなんとかして情報
>  を渡す必要があります.
>
>  今,話題に登っているのは,3の場合にいろいろと面倒だ,と言
>  うものです(よね).

です.

(中略)

たぶん, 私の例外に対する考え方が ruby の指向るものと違っているせいかも
知れません.

その前に, 私の例外に対する考え方を説明しましょう.

松本氏は知っていると思いますが, 現在, 私はオブジェクト指向データベース
やさんです. このデータベースシステムは, C++をベースにプログラムを組む
のですが, エラーに関しては, 例外ベースとなっています. 例外は結構取り扱っ
ているつもりです.

で, エラーは例外ベースになっているのですが, データベースシステムそのも
のは, サーバ/クライアントをとっています. この様なシステムですと, 大体3
津のカテゴリに分かれると思います:

1. 私の関係ないところの例外(例えば, サーバが落ちた/ネットワークが落ちた)
2. コーディングの間違い(バグ)に由来する例外
3. 最初から例外を発生させることを前提とした例外(例えば, コレクションを
   検索して求める要素が存在しなければ, 例外が発生するとか) 

これらで1,2は, どうせ対した対処はできませんので, 松本氏のいう通りだと
思います. 問題は3の場合です.

3の例外を利用するようなプログラムを書いたとします. ところが問題になる
のは, 3のブロックの中で対象となる例外が発生することがありうることです.

つまり, 先ほどの例をruby風に記述すると:

begin 
  elm = コレクションの検索を行なう
rescue
  elm = nil
end

などのようなコーディングを行なうと, その他の例外が発生した時も何事もな
かったように処理を続けてしまうので困るわけです.

結局, 3の処理を行ないたい場合例外の捕捉は目的としているもの*だけ*を正
しくとらえないと間違った動作を行なう可能性があるわけです.

と, ここまでは私が使っている OODB でのプログラミングの話しです. 当然,
ruby における例外の捉え方とは違っていると思います.

では, rubyにおける例外とは何でしょうか?

A. 例外処理 == エラー処理
B. 例外処理 == 通常の処理とは違う処理を行なうため.

rubyの例外の目的が (A)であるならば, 現在の仕様で全然問題ないと思います.
(B)を目的とするのであれば, 個別の例外について捉えやすくするような仕組
みが必要になると思います.

私が, 個別に例外を拾いたいと思ったのはまさに(B)のケースでした.

begin
  uname = Etc.getpwuid(uid).name
rescue
  uname = uid.to_s
end

上記のような処理を行ないたかったのですね. 何らかの理由で/etc/passwdに
そのuidがなければ, しょうがないのでuidを表示したかったわけです. 

でも, もし,

begin
  uname = Etc.getpwuid(uid).uname
rescue
  uname = uid.to_s
end

なんてしていたら, どうなります? pwの構造体にはunameなんてメンバはない
ので例外が発生します. で, それはresqueで捉えられて とりあえず 動作して
しまいます. これは, (3)の処理をするつもりで(2)まで拾ってしまった例です
ね. 

ruby では この様な(B)のタイプの例外処理は, 推薦しないということなので
しょうか? このようなタイプの例外処理はそんなに少なくはないと思うのです
が...

>  類の例外案が載っています(3年前の5月のものです).
>
>    * Icon式例外(失敗が偽)
>    * 単純型(今のrubyのもの)
>    * 名前つき例外
>    * 名前つき値あり例外(CLU式)
>
>  んで,結局上で述べたように,rubyの対象とする領域では個々の
>  例外を区別する必要はそれほど無くて,例外処理機能は単純なも
>  ので良いだろうとの結論を出したわけです.その決断が正しかっ
>  たかどうかはまだ結論は出ていないようですが,個人的にはCLU
>  式の例外処理(今はC++やJavaもこのタイプの例外機能を持ってい
>  ますね)よりも「お手軽」で良いと思っています.

たぶん, 松本氏の考える例外は先ほどの(A)なのでしょうね...

>というようなわけで,私はrubyの例外機能はあのままで良くて,た
>だドキュメントには(いつか)メソッドが発生させうる例外をきちん
>と明示した方が良いと思うのです.少なくとも,あるメソッドが例
>外を発生させうるかどうかという情報は必須ですね.今はそれさえ
>ないものがあるので.

私は機能を拡張してほしいといっているつもりはなくて, メッセージレベルで
工夫をすればもっと使いやすくなるのでは? といいたいだけです. それだけで
(B)のケースの例外処理も行ないやすくなるわけです.

__
..........................................石塚 圭樹@SHLジャパン(株)...
------------->アドレス変わりました!! e-mail: keiju / shljapan.co.jp <----