[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]