From: matz@... (Yukihiro Matsumoto) Date: 1996-08-13T01:10:09+09:00 Subject: [ruby-list:407] Re: about exception まつもと ゆきひろです. 長いです. In message "[ruby-list:405] Re: about exception" on 96/08/12, Keiju ISHITSUKA writes: |けいじゅ@SHLジャパンです. |段階を追っていけばそういうことになりますよね. 現在は, | | * それはどのくらい問題なのか | |という段階だと思っています. |例外の機能と 現在あるライブラリ群の例外の発生の仕方のバランス なのかな? |という気がしています. |例を挙げれば, File.open() などは, 例外で対処すべきものではないのかも知 |れません. indexとかと同じで nil を帰すようにするわけですね. バランスの見直しはあるいは必要かも知れませんが,File.openに 関しては私は賛成できません.というのも,File.openが失敗した 場合,nilを返すと言うことは結局必ず例外処理のコードを書かな いといけなくなることを意味します(でないとnilにメッセージを送っ てエラーになり,現在よりもエラーメッセージが分かりにくくなる). それは避けたいです. file = File.open(fname) だけでもちゃんと動き(例外が起こればそれに応じたメッセージが 表示され),例外処理をすればそれなりに対処できるものでないと. # そういう意味ではEOFは例外の方が良かったかも知れない. |というわけですから, 最初のフェーズをもうちょっと考えてみましょう. それには賛成です. 今まで話した中で,現在の例外の仕様で問題があると思われた点は 以下のものがあります. (1) Interruptがデフォルトで例外に変換されるので,思わぬ rescueで捕捉されてしまう. (2) 変数名/メソッド名のスペルミスなどの思わぬ例外もrescue で捕捉されてしまう. (3) UNIX間はともかく他のOSに移植された時に例外のメッセージ が変わってしまう可能性がある. (4) 例外メッセージにスペルミスがあってもコンパイル時に検出 できない.あるいは意味的に同じ例外に違うメッセージが割 り当てられる可能性がある. 石塚さんは他にもいくつかあげているようですが,本質的なのはこ れらでしょう. 1は確かに問題だと思います.これはデフォルトをexitかthrowにす る方向で検討します. 3は他のOSに移植する時にメッセージをUNIXに合わせる方向で実装 することで対応できると思います.つまり例外の仕様の問題ではな く,実装の問題だと思います.UNIX間ならメッセージは共通である と考えて良いでしょう. 4は私には本質的だとは思えません.たとえいくらか検出しにくい としてもスペルミスはバグですし,あくまで実装の問題です.また, 石塚さんは意味的に同じ例外に異なったメッセージがマッピングさ れることを問題だと感じていらっしゃるようですが,私はそれほど 問題だとは思っていません(後述). となると残りは2ですが,これもかなりの場合は文字列の分岐でな んとかなりそうな気がします.もっとも前のメイルにも書いたよう にいくつかの例外は「エラー」と言う例外とは別の括りにした方が 良いかも知れないので,これは継続して検討します. |将来的に, 色々な人がクラス/モジュールを提供する様になった場合を考えて |みて下さい. その場合, 各々独自にメッセージを作るようになると収集がつか |なくなる様な気がしませんか? 当然, 唯一性の保証もなくなりますし... 唯一性の保証って必要なんですか? あるいは収集がつかなくなると はどういう事態のことですか? たぶんここが一番食い違っているところだと思います. 例えば,対象が存在しなかった時のFile.openとDir.openのメッセー ジが全く異なっていたら,若干使いにくいかも知れませんが,本質 的な問題だとは思えません.むしろ例えば File.open - No such file Dir.open - No such directory の方が分かりやすい可能性だってありますよね.私には唯一性の保 証が必要になる局面が想像できないんですけど,どういう場合が考 えられますか? 例外のメッセージが不統一になりがちだという指摘にはIDやSYMBOL を使っても統一する気が無ければ統一されないし,統一する気があ れば文字列でも統一されると答えておきます(ちょっと説得力弱い). |とここまで書いて気になったのですが, 例外を発生させるのはライブラリ側が |主であると考えているのですが, 違いますか? ライブラリとなることを目的と |して作られたもの以外の通常のプログラム(関数など)も例外を出すことは考え |ていませんよね? そのような仮定は置いていません.確かに私は,OOPには単なるク ラスライブラリの利用者としての立場とクラスライブラリ作成者の 立場があり,両方を支援すべきだと考えていますし,その考えにし たがってrubyではクラスライブラリを利用した従来型プログラミン グも可能なように設計されています. しかし,同時に単なるクラスライブラリの利用者がクラスライブラ リの作成者に簡単にステップアップできるように両者の垣根は低く あって欲しいとも考えています.よって例外の使い方にそのような (ライブラリ開発者だけが使うという)仮定を置きたくない気持があ ります. |特に, 将来のことを考えると, このぐらいの仕組みはちゃんと決めておかない |と大変なことになるのではと心配します. 例外について良く考えることは非常に重要なことだと思います. さて,例によってまとめておきましょう. まず現在の例外処理の問題(の可能性)は * 予想しない例外を捕捉してしまう(特にinterrupt/スペルミス) * 同じ意味の例外に違うメッセージが割り当てられてしまう可能 性がある. 個人的には後者を問題だとは認識していないんですけど. そしてメリットは * (逆接的だが)例外の種別を気にする必要が無い * 仕組みが簡単で(ほとんどの場合)記述も簡単 だと思います. ここで例外にIDを導入した場合,メリットは * いろいろな例外にきめ細かく対応できる. * 同じ意味の例外に同じ名前(種別)を割り当てやすい 私は前者はそれほど必要ないとまだ思っています.もちろん前述の いくつかの問題については認識しましたので,なんらかの検討を行 います(が,おそらく例外とは違う枠組で対応すると思います).後 者もあまり必要だと思っていません. デメリットは * 発生する例外を覚えている(あるいは調べる)必要がある. * 例外処理の記述が複雑になる. * 例外を発生させる人にとって面倒(例外をいちいち定義,参照 する必要がある). だと思います. と言うわけで石塚さんが私を説得するストラテジーとしては, + (interruptなど以外で)文字列の分岐では本質的に問題がある例 + (クラス毎などある単位で)例外種別を一元管理することの優位性 を示すのがベストだと思われます. ちなみに石塚案を元に私が新しい例外機能を設計するならばこうい う感じになるでしょう. class Foo