[ruby-dev:47220] [ruby-trunk - Feature #7767] Tempfileで自動的にファイルを削除する

From: "shugo (Shugo Maeda)" <redmine@...>
Date: 2013-04-04 09:34:11 UTC
List: ruby-dev #47220
Issue #7767 has been updated by shugo (Shugo Maeda).


akr (Akira Tanaka) wrote:
>  > メソッド名ですが、
>  > * 使いやすさを考えると、openと同じくらいに書きやすい(短い)ものがよい
>  > * Tempfile.openはブロックを抜けるときにcloseするが、提案する新メソッドではclose!する
>  > という点を考えて、ひとまずTempfile.open!を提案してみます。
>  
>  名前が通るといいですねぇ。

Tempfile.openとTempfile.open!で違うクラスのインスタンスが作成されるのは
ちょっとわかりにくいような気がしますので、openから派生した名前でない方がよいの
ではないでしょうか。
例えば、Tempfile.createはどうでしょう。

----------------------------------------
Feature #7767: Tempfileで自動的にファイルを削除する
https://bugs.ruby-lang.org/issues/7767#change-38212

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/

In This Thread