Improved Tempfile w/o DelegateClass
I propose improved
Tempfile has following problems.
t = Tempfile.new("foo") #=> #<File:/tmp/foo20121012-6762-12w11to> t.is_a? File #=> false
t = Tempfile.new("foo") t.dup.close t.read #=> IOError: closed stream
finalizer performs unlink even when it has been duplicated
t = Tempfile.new("foo") path = t.path #=> "/tmp/foo20121012-7533-1q537gq" File.exist? path #=> true tt = t.dup t = nil GC.start File.exist? path #=> false
I think these problems caused by using
Therefore, I made a patch to resolve the problems.
The patched Tempfile class is a subclass of File.
Updated by Anonymous almost 7 years ago
In message "Re: [ruby-core:47930] [ruby-trunk - Feature #7148][Open] Improved Tempfile w/o DelegateClass"
on Fri, 12 Oct 2012 14:04:08 +0900, "Glass_saga (Masaki Matsushita)" firstname.lastname@example.org writes:
I propose improved
Tempfilehas following problems.
- confusing inspect
- finalizer performs unlink even when it has been duplicated
I have no objection about (1), but what we expect when we call
Tempfile#dup might differ, for example, I'd expect it to copy the
underlying temporary file. So making
Tempfile a subclass of
may not be the ideal solution.
Updated by Glass_saga (Masaki Matsushita) almost 7 years ago
Yukihiro Matsumoto wrote:
I'd expect it to copy the underlying temporary file.
Is the behavior of #dup you expect like the following?
def dup dupe = self.class.new(@basename) IO.copy_stream(self, dupe, 0) dupe end
I think the reason why
DelegateClass is that to implement
Tempfile#open without it used to be difficult.
To implement it as subclass of
self must be reopened with full configuration, mode and opts.
IO#reopen used not to accept them, but now it accepts after r37071.
Updated by normalperson (Eric Wong) about 4 years ago
"Glass_saga (Masaki Matsushita)" email@example.com wrote:
I would still like this for 2.3.0, just hit a snag with
Also, Charles hit a similar problem not long ago, too:
[ruby-core:68700] [Bug #11015]
Updated by matz (Yukihiro Matsumoto) about 4 years ago
It's OK for me to implement Tempfile without using DelegateClass. If JRuby does similar thing already, it might be a good idea to share implementation. Besides that, we might need to think about killing/redefining some unnecessary/invalid methods of File class, e.g. reopen. I am afraid dup is one of them.
Updated by sowieso (So Wieso) 4 months ago
I guess this is related:
tf = Tempfile.new tf.unlink tf2 = tf.dup puts tf.fileno # => 10 puts tf2.fileno # => 11 tf2.close print tf2.fileno # => 11 print tf.fileno IOError: closed stream from /usr/local/rvm/rubies/ruby-2.6.0/lib/ruby/2.6.0/delegate.rb:349:in `fileno'
It closes the wrong fd. Using normal
File instead of
Tmpfile makes it work like usual.
Libraries that accept an IO object and duplicate it internally don't work correctly with
Tempfile (in my case rubyzip). This really needs a fix.