例外処理の構文
Javaのソースを読んでいると、例外構文がウザく感じることがあります。try-catchによってインデントが起きていると、インデントは制御構造だという前提で読んでいるとどうも読みづらい。
これはRubyでも本質的には同じです。Javaのtry-catchはRubyではbegin-rescueで書き、通常、そこで字下げをします。しかし、例外はあくまで例外処理なわけで、その例外的な処理の為にインデントされているのはどうもしっくり来ないのです。もちろん、例外をエラーハンドリングによるある処理からのgotoとして使う場合には、その処理の範囲が示されているのでいいと思うのですが、ファイルオープンする処理をまた例外の範囲としてインデントするのはどうも冗長のように感じます。
ただ、Rubyを書いていてあまり例外処理が気にならないのは、単にJavaと違って、発生する例外をすべてハンドルする必要はないってだけかもしれません。Javaの投げる可能性のある例外には、ちゃんとハンドラを書いておかなければいけないというルール自体はそんなに悪いものじゃないと思うんですが。
ひとつの疑問として、「はたして、例外処理は例外が発生するコード範囲をちゃんと指定しないといけないのか」ということはありますが、これについてはあんまりマジメに考えてません。そもそも、メソッドを本文+catch部分+finally部分と分けて記述するというキマリであれば、if-else if -elseと同じなんですから
public void hoge(String fuga) throws someException { try {
//本来の処理
} catch(someException se){
//例外処理
} catch {
//その他の例外処理
} finally {
//終了処理
}}
でいいんじゃないかという気もします。ああ、なんかスッキリ。
それよりも、インデントを使用する構文は制御構造の記述に特化して、何か他の範囲指定構文はあり得ないんでしょうか。
例えば、コメントの構文があります。/* */ や、<!-- -->による範囲指定は例外処理でも有用かもしれません。まあ、すでにそのやりかたはコメントで使ってるんだからだめだという気もしますけど(笑)
コメントは大抵、行頭に指定するので後置構文はどうでしょう。単純に今の構文を逆にしてみるだけでもいいかも知れません。Rubyの後置構文結構好きなんですよ
f.gets unless f == null
みたいな感じの。例えば
URL url = new URL(sourceURL) try(Exeption e);
Object content = url.getContent();
if ( content instanceof InputStream ) {
String line;
BufferedReader reader = new BufferedReader( new InputStreamReader((InputStream)content, "JISAutoDetect" ) );
while ( ( line = reader.readLine() ) != null )
source.append(line+"\n");
}
catch( e.getClass == IOException) {
source.append("<html></html>");
}
だみだ・・・わかりにくい。後置は所詮、前が一文じゃないとだめですな。なんかいいアイデアはないものでしょうか。
「日記・コラム・つぶやき」カテゴリの記事
- 沖縄の美ら海水族館に行ってきた。そのはち(2025.01.02)
- 沖縄の美ら海水族館に行ってきた。そのなな(2025.01.01)
- 沖縄の美ら海水族館に行ってきた。そのろく(2025.01.01)
- 沖縄の美ら海水族館に行ってきた。そのご(2024.12.31)
- 沖縄の美ら海水族館に行ってきた。そのよん(2024.12.14)
Comments
Javaの例外には2種類あって、Checkedな例外とRuntimeな例外がある。前者はcatchするかthrows節が必要だが、後者はcatchをしなくて良い。
Javaの例外処理は長いこと問題になっていて、例外処理をどう処理することが一番良いのかということは長い間フレームワークの作者等の間で問題になっていた。
良くあるのはRuntime例外でラップしてしまってとにかく上に投げるものだが、これには問題もある。
とりあえずベルギーのユーザーグループがJava7にて採用するように提案しているJSRがあって、それを見るとcatch文に複数の例外型を記述できたり、catchの型宣言にfinal属性を用いるとリスローがthrows節無しでできたりできるように提案されている。
http://www.bejug.org/newsletter/05/index.html
あと、ジョークなのだがJSR-666てのもあってこちらでも例外の扱いについて論じられており、defaultの挙動としてcatchがない場合自動的にthrows扱いにすることや、nullを廃止してNullPointerExceptionを廃止すること等が提案されている。
http://java.dzone.com/news/jsr-666-solving-javas-problems
個人的には例外処理とロギングが言語レベルでなんとかしてほしい。
ログ取って異常終了するくらいしかやれることはあまりないし。
Posted by: こ | March 24, 2008 09:15 PM
うーん、なんか論点がよくわからんのだが、
例外処理は本質的にはハイレベル制御構造(と勝手に思っている)なので
インデントで構わないと思うぞ。
それに、インデントを強要されるPythonなんかではな、(以下略)
Posted by: nac | March 25, 2008 01:36 AM
C++みたいにこんな風に書ければ良いのですかなー。
public void hoge(String fuga) throws someException try {
//本来の処理
} catch(someException se){
//例外処理
} catch {
//その他の例外処理
} finally {
//終了処理
}
Posted by: Yugui | March 27, 2008 09:29 AM