Feature #7148
open
Improved Tempfile w/o DelegateClass
Added by Glass_saga (Masaki Matsushita) about 12 years ago.
Updated over 5 years ago.
Description
I propose improved Tempfile
without DelegateClass()
.
Present Tempfile
has following problems.
-
confusing inspect
t = Tempfile.new("foo") #=> #<File:/tmp/foo20121012-6762-12w11to>
t.is_a? File #=> false
-
#dup
doesn't duplicate IO
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 DelegateClass()
.
Therefore, I made a patch to resolve the problems.
The patched Tempfile class is a subclass of File.
Files
Hi,
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)" glass.saga@gmail.com writes:
I propose improved Tempfile
without DelegateClass()
.
Present Tempfile
has following problems.
- confusing inspect
-
#dup
doesn't duplicate IO
- 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 File
may not be the ideal solution.
matz.
Hello,
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 Tempfile
uses DelegateClass
is that to implement Tempfile#open
without it used to be difficult.
To implement it as subclass of File
, self
must be reopened with full configuration, mode and opts.
IO#reopen
used not to accept them, but now it accepts after r37071.
JRuby has been running with Tempfile < File
for a couple years now, and have received only minor bug reports about it. It works very well, and has no delegation cost.
Are there some reasons not to make Tempfile
a subclass of File
?
I think it's a better solution, even if it's not an ideal solution.
- Status changed from Open to Assigned
- Assignee set to matz (Yukihiro Matsumoto)
- Priority changed from Normal to 3
- Target version set to 2.6
I think the problem you faced was resolved at r50118, wasn't it?
Sadly, r50118 actually caused my problem because I was using src_offset
for IO.copy_stream
It doesn't sound like anyone opposes this idea, so are we just missing implementation?
- Description updated (diff)
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.
Matz.
- Assignee changed from matz (Yukihiro Matsumoto) to Glass_saga (Masaki Matsushita)
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.
- Related to Bug #17144: Tempfile.open { ... } does not unlink the file added
Also available in: Atom
PDF
Like0
Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0Like0