Project

General

Profile

Feature #7767

Feature #5707: temporary file creation without finalizer and delegate.

Tempfileで自動的にファイルを削除する

Added by kyanagi (Kouhei Yanagita) over 7 years ago. Updated over 7 years ago.

Status:
Closed
Priority:
Normal
Target version:
[ruby-dev:46902]

Description

ソースコードのコメント(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

Also available in: Atom PDF