lethevert is a programmer このページをアンテナに追加 RSSフィード

28/8/2007 (Tue) 晴れ

Ruby: えっと・・・これはネタですか?

(何を言いたいか分からないエントリだったので、少し整理して、追記しました)

http://www.rubyist.net/~matz/20070820.html#p02

そういう風に書かせないために、チェック例外があるのでしょうがorz

例外はむしろチェックされない例外があることのほうが問題。(参考→id:lethevert:20070817:p1

----

Rubyのコードもそうだけれど、元の記事のJavaのプログラムも、プログラムが下手すぎ。これで十分。

String readData(File file, String default_value) {
  BufferedReader in = null;
  try {
    in = new BufferedReader(new FileReader(file));
    return in.readLine();
  }catch(IOException e) {
    return default_value;
  }finally{
    try{ in.close();}catch(Throwable _){}
  }
}

----

close()で全部例外をつぶしているのは、本文から投げられた例外を隠さないためで、RuntimeExceptionだろうがErrorだろうが全部catchして無視する意図です。close()で何が起きても、その後の処理に影響があることはまずないという判断です。なにも記録が残らないのが気になるなら、

    try{ in.close();}catch(Throwable e){ log.warn(e);}

としておけばいいかと。

----

元のRubyのコードが何がorzかというと、

def read_data(file)
  begin
    file.readline
  ensure
    file.close
  end
end

Javaで書き直せば、

String read_data (BufferedReader file) throws Throwable {
  try{
    return file.readLine();
  }finally{
    file.close();
  }
}

と書いているのと同じですよね。

  1. read_dataから例外が洩れるのは意図的なの?
  2. closeで例外が出たらreadlineの例外を隠すんじゃないの?
  3. チェック例外じゃないことで、例外の問題に気づかずにスルーしてしまう危険はないの?
  4. IOエラーって単体テストで必ずチェックしているものなの?
  5. どこで例外が発生するか分からないプログラムを書くのって恐くないの?

それから、これも気になった。

  1. オープンしたファイルをわたすの?(Rubyはファイルオブジェクトを作ったらデフォルトでファイルをオープンするの?)

名無し名無し 2007/08/29 00:11 > close()で何が起きても、その後の処理に影響があることはまずないという判断です。

ファイルのクローズのエラーは、無視できない大きな問題だと思いますが。

lethevertlethevert 2007/08/29 00:59 ではどのように書くのが適切でしょうか?
コードをあげて説明していただけますか?

odzodz 2007/08/29 09:35 記録を残せばまだいいんでしょうけど、Error を catch しちゃっていいのかな、という気はします。
OutOfMemoryError、StackOverflowError などなど、下手に catch すると問題が分かりにくくなるかなぁ、と。

lethevertlethevert 2007/08/29 11:10 OutOfMemoryErrorはつぶしても問題ないと思います。StackOverflowErrorがcloseで起こるというのはライブラリがバグっているような・・・
なお、業務用の自作ライブラリの場合は、必要なログは、closeの実装の側で取ってしまいますので。

odzodz 2007/08/31 01:23 いや、まさにそういうバグっているのを見逃す可能性という話です。標準ライブラリは信頼、自作ライブラリはライブラリ側でログを取るとしてもこのケースでは当てはまらないけど、サードパーティ製ライブラリもありますし。

lethevertlethevert 2007/08/31 08:39 もちろん、ケースバイケースでログは取得します。取ってはいけないという考えではないですし、むしろ危険を感じたら必ずログを取ります。仕事では自分のコードは自分で保守するので。
ただ、基本的にcloseから意味のある例外が出てくると、経験的にtry..catch..finallyの構文ではきれいにかけないという風に感じています。それがtry..catch..finallyの限界だという考えです。なので、次のエントリにも書いたように、書き込み処理ではcommit処理とclose処理が分かれるような書き方を探すようにしています。
あと、必ず取っておきたいログがあるなら、コードの読みやすさのためにも、書き忘れを防ぐためにも、ラッパークラスを書いてそこでログを取るようにします。そういうところではログを取ることがテーマなので、冗長な書き方も辞さずに丁寧に書きます。

lethevertlethevert 2007/08/31 08:48 「つぶす」という表現は、例外を受けて回復処理をしたり、例外を再送したりすることなく、その場で例外を消してしまうということを言っているので、「ログを取る」ということとは矛盾してないつもりですけど、そういう風には読めなかったということでしょうか。
ログを取っても、処理を回復もせず中断もしないなら、それはプログラムとしては例外に対して何もしていないのと同じだと思うので、「つぶす」という言葉が適当だという感性だったのですが。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/lethevert/20070828/p2
 
Connection: close