From: "ko1 (Koichi Sasada)" Date: 2013-02-22T09:07:45+09:00 Subject: [ruby-dev:47065] [ruby-trunk - Feature #7767] Tempfileで自動的にファイルを削除する Issue #7767 has been updated by ko1 (Koichi Sasada). Assignee set to akr (Akira Tanaka) 誰にアサインすればわからなかったのですが、 詳しそうな田中さんにアサインさせて頂きます。 ---------------------------------------- Feature #7767: Tempfileで自動的にファイルを削除する https://bugs.ruby-lang.org/issues/7767#change-36736 Author: kyanagi (Kouhei Yanagita) Status: Open Priority: Normal Assignee: akr (Akira Tanaka) Category: lib Target version: next minor ソースコードのコメント(tempfile.rbのGood practicesの項)にも書かれている通り、 Tempfileは使用後、明示的に削除することが推奨されています。 しかし、Tempfile.openにブロックを渡すと自動的にcloseするところまではやってくれるのに、 削除をわざわざ明示的に書かないといけないというのは少し残念な気もします。 Tempfile.openの類推で、ブロックを抜けると自動的にclose!してくれるメソッドがあると、 削除に気を使わなくてもよくなり、使いやすいのではないかと思いましたがいかがでしょうか。 メソッド名ですが、 * 使いやすさを考えると、openと同じくらいに書きやすい(短い)ものがよい * Tempfile.openはブロックを抜けるときにcloseするが、提案する新メソッドではclose!する という点を考えて、ひとまずTempfile.open!を提案してみます。 Index: lib/tempfile.rb =================================================================== --- lib/tempfile.rb (revision 39003) +++ lib/tempfile.rb (working copy) @@ -305,6 +305,9 @@ # # In any case, all arguments (+*args+) will be passed to Tempfile.new. # + # +open!+ is same as +open+, except that the file will be deleted immediately + # after the block terminates. + # # Tempfile.open('foo', '/home/temp') do |f| # ... do something with f ... # end @@ -316,14 +319,23 @@ # ensure # f.close # end - def open(*args) + def open(*args, &block) + _open(false, *args, &block) + end + + def open!(*args, &block) + _open(true, *args, &block) + end + + private + def _open(unlink_at_block_end, *args, &block) tempfile = new(*args) if block_given? begin yield(tempfile) ensure - tempfile.close + tempfile.close(unlink_at_block_end) end else tempfile Index: test/test_tempfile.rb =================================================================== --- test/test_tempfile.rb (revision 39003) +++ test/test_tempfile.rb (working copy) @@ -304,5 +304,13 @@ assert_equal(0600, t.stat.mode & 0777) end end + + def test_open_bang_with_block + path = nil + Tempfile.open!('foo') do |f| + path = f.path + end + assert !File.exist?(path) + end end -- http://bugs.ruby-lang.org/