ruby-changes:38601
From: glass <ko1@a...>
Date: Sat, 30 May 2015 10:30:12 +0900 (JST)
Subject: [ruby-changes:38601] glass:r50682 (trunk): * lib/tempfile.rb: refactoring.
glass 2015-05-30 10:29:48 +0900 (Sat, 30 May 2015) New Revision: 50682 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=50682 Log: * lib/tempfile.rb: refactoring. * use warn instead of STDERR.print * remove @tmpname and use @tmpfile.path * introduce @unlinked flag * Remover takes only @tmpfile * mode will be modified just before file reopen Modified files: trunk/ChangeLog trunk/lib/tempfile.rb Index: ChangeLog =================================================================== --- ChangeLog (revision 50681) +++ ChangeLog (revision 50682) @@ -1,3 +1,12 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Sat May 30 10:26:09 2015 Masaki Matsushita <glass.saga@g...> + + * lib/tempfile.rb: refactoring. + * use warn instead of STDERR.print + * remove @tmpname and use @tmpfile.path + * introduce @unlinked flag + * Remover takes only @tmpfile + * mode will be modified just before file reopen + Sat May 30 09:02:51 2015 Eric Wong <e@8...> * include/ruby/intern.h (rb_generic_ivar_table): deprecate Index: lib/tempfile.rb =================================================================== --- lib/tempfile.rb (revision 50681) +++ lib/tempfile.rb (revision 50682) @@ -123,41 +123,29 @@ class Tempfile < DelegateClass(File) https://github.com/ruby/ruby/blob/trunk/lib/tempfile.rb#L123 # If Tempfile.new cannot find a unique filename within a limited # number of tries, then it will raise an exception. def initialize(basename="", tmpdir=nil, mode: 0, **options) - if block_given? - warn "Tempfile.new doesn't call the given block." - end - @data = [] - @clean_proc = Remover.new(@data) - ObjectSpace.define_finalizer(self, @clean_proc) + warn "Tempfile.new doesn't call the given block." if block_given? + @mode = mode|File::RDWR|File::CREAT|File::EXCL ::Dir::Tmpname.create(basename, tmpdir, options) do |tmpname, n, opts| - mode |= File::RDWR|File::CREAT|File::EXCL opts[:perm] = 0600 - @data[1] = @tmpfile = File.open(tmpname, mode, opts) - @data[0] = @tmpname = tmpname - @mode = mode & ~(File::CREAT|File::EXCL) - opts.freeze - @opts = opts + @tmpfile = File.open(tmpname, @mode, opts) + @opts = opts.freeze end + ObjectSpace.define_finalizer(self, Remover.new(@tmpfile)) super(@tmpfile) end # Opens or reopens the file with mode "r+". def open - @tmpfile.close if @tmpfile - @tmpfile = File.open(@tmpname, @mode, @opts) - @data[1] = @tmpfile + _close + mode = @mode & ~(File::CREAT|File::EXCL) + @tmpfile = File.open(@tmpfile.path, mode, @opts) __setobj__(@tmpfile) end def _close # :nodoc: - begin - @tmpfile.close if @tmpfile - ensure - @tmpfile = nil - @data[1] = nil if @data - end + @tmpfile.close unless @tmpfile.closed? end protected :_close @@ -168,18 +156,14 @@ class Tempfile < DelegateClass(File) https://github.com/ruby/ruby/blob/trunk/lib/tempfile.rb#L156 # If you don't explicitly unlink the temporary file, the removal # will be delayed until the object is finalized. def close(unlink_now=false) - if unlink_now - close! - else - _close - end + _close + unlink if unlink_now end # Closes and unlinks (deletes) the file. Has the same effect as called # <tt>close(true)</tt>. def close! - _close - unlink + close(true) end # Unlinks (deletes) the file from the filesystem. One should always unlink @@ -216,37 +200,32 @@ class Tempfile < DelegateClass(File) https://github.com/ruby/ruby/blob/trunk/lib/tempfile.rb#L200 # # to do so again. # end def unlink - return unless @tmpname + return if @unlinked begin - File.unlink(@tmpname) + File.unlink(@tmpfile.path) rescue Errno::ENOENT rescue Errno::EACCES # may not be able to unlink on Windows; just ignore return end - # remove tmpname from remover - @data[0] = @data[1] = nil - @tmpname = nil ObjectSpace.undefine_finalizer(self) + @unlinked = true end alias delete unlink # Returns the full path name of the temporary file. # This will be nil if #unlink has been called. def path - @tmpname + @unlinked ? nil : @tmpfile.path end # Returns the size of the temporary file. As a side effect, the IO # buffer is flushed before determining the size. def size - if @tmpfile - @tmpfile.flush - @tmpfile.stat.size - elsif @tmpname - File.size(@tmpname) + if !@tmpfile.closed? + @tmpfile.size # File#size calls rb_io_flush_raw() else - 0 + File.size?(@tmpfile.path) end end alias length size @@ -261,28 +240,23 @@ class Tempfile < DelegateClass(File) https://github.com/ruby/ruby/blob/trunk/lib/tempfile.rb#L240 end class Remover - def initialize(data) - @pid = $$ - @data = data + def initialize(tmpfile) + @pid = Process.pid + @tmpfile = tmpfile end def call(*args) - return if @pid != $$ - - path, tmpfile = @data - - STDERR.print "removing ", path, "..." if $DEBUG + return if @pid != Process.pid - tmpfile.close if tmpfile + warn "removing #{@tmpfile.path}..." if $DEBUG - if path - begin - File.unlink(path) - rescue Errno::ENOENT - end + @tmpfile.close if @tmpfile.closed? + begin + File.unlink(@tmpfile.path) + rescue Errno::ENOENT end - STDERR.print "done\n" if $DEBUG + warn "done" if $DEBUG end end -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/