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

ruby-changes:12933

From: naruse <ko1@a...>
Date: Wed, 26 Aug 2009 21:51:18 +0900 (JST)
Subject: [ruby-changes:12933] Ruby:r24672 (trunk): * lib/tempfile.rb: add documents from Hongli Lai's fork.

naruse	2009-08-26 21:50:57 +0900 (Wed, 26 Aug 2009)

  New Revision: 24672

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=24672

  Log:
    * lib/tempfile.rb: add documents from Hongli Lai's fork.
      cf [ruby-core:25131].

  Modified files:
    trunk/ChangeLog
    trunk/lib/tempfile.rb

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 24671)
+++ ChangeLog	(revision 24672)
@@ -1,3 +1,8 @@
+Wed Aug 26 21:49:23 2009  NARUSE, Yui  <naruse@r...>
+
+	* lib/tempfile.rb: add documents from Hongli Lai's fork.
+	  cf [ruby-core:25131].
+
 Wed Aug 26 19:51:13 2009  NARUSE, Yui  <naruse@r...>
 
 	* tool/mkconfig.rb (program_transform_name): fix for multiple trans
Index: lib/tempfile.rb
===================================================================
--- lib/tempfile.rb	(revision 24671)
+++ lib/tempfile.rb	(revision 24672)
@@ -8,27 +8,129 @@
 require 'tmpdir'
 require 'thread'
 
-# A class for managing temporary files.  This library is written to be
-# thread safe.
+# A utility class for managing temporary files. When you create a Tempfile
+# object, it will create a temporary file with a unique filename. A Tempfile
+# objects behaves just like a File object, and you can perform all the usual
+# file operations on it: reading data, writing data, changing its permissions,
+# etc. So although this class does not explicitly document all instance methods
+# supported by File, you can in fact call any File instance method on a
+# Tempfile object.
+#
+# == Synopsis
+#
+#   require 'tempfile'
+#   
+#   file = Tempfile.new('foo')
+#   file.path      # => A unique filename in the OS's temp directory,
+#                  #    e.g.: "/tmp/foo.24722.0"
+#                  #    This filename contains 'foo' in its basename.
+#   file.write("hello world")
+#   file.rewind
+#   file.read      # => "hello world"
+#   file.close
+#   file.unlink    # deletes the temp file
+#
+# == Good practices
+#
+# === Explicit close
+#
+# When a Tempfile object is garbage collected, or when the Ruby interpreter
+# exits, its associated temporary file is automatically deleted. This means
+# that's it's unnecessary to explicitly delete a Tempfile after use, though
+# it's good practice to do so: not explicitly deleting unused Tempfiles can
+# potentially leave behind large amounts of tempfiles on the filesystem
+# until they're garbage collected. The existance of these temp files can make
+# it harder to determine a new Tempfile filename.
+#
+# Therefore, one should always call #unlink or close in an ensure block, like
+# this:
+#
+#   file = Tempfile.new('foo)
+#   begin
+#      ...do something with file...
+#   ensure
+#      file.close
+#      file.unlink   # deletes the temp file
+#   end
+#
+# === Unlink after creation
+#
+# On POSIX systems, it's possible to unlink a file right after creating it,
+# and before closing it. This removes the filesystem entry without closing
+# the file handle, so it ensures that only the processes that already had
+# the file handle open can access the file's contents. It's strongly
+# recommended that you do this if you do not want any other processes to
+# be able to read from or write to the Tempfile, and you do not need to
+# know the Tempfile's filename either.
+#
+# For example, a practical use case for unlink-after-creation would be this:
+# you need a large byte buffer that's too large to comfortably fit in RAM,
+# e.g. when you're writing a web server and you want to buffer the client's
+# file upload data.
+#
+# Please refer to #unlink for more information and a code example.
+#
+# == Minor notes
+#
+# Tempfile's filename picking method is both thread-safe and inter-process-safe:
+# it guarantees that no other threads or processes will pick the same filename.
+#
+# Tempfile itself however may not be entirely thread-safe. If you access the
+# same Tempfile object from multiple threads then you should protect it with a
+# mutex.
 class Tempfile < DelegateClass(File)
   MAX_TRY = 10  # :nodoc:
   @@cleanlist = []
   @@lock = Mutex.new
 
-  # Creates a temporary file of mode 0600 in the temporary directory,
-  # opens it with mode "w+", and returns a Tempfile object which
-  # represents the created temporary file.  A Tempfile object can be
-  # treated just like a normal File object.
+  # call-seq:
+  #    new(basename, [tmpdir = Dir.tmpdir], [options])
   #
-  # The basename parameter is used to determine the name of a
-  # temporary file.  If an Array is given, the first element is used
-  # as prefix string and the second as suffix string, respectively.
-  # Otherwise it is treated as prefix string.
+  # Creates a temporary file with permissions 0600 (= only readable and
+  # writable by the owner) and opens it with mode "w+".
   #
-  # If tmpdir is omitted, the temporary directory is determined by
-  # Dir::tmpdir provided by 'tmpdir.rb'.
-  # When $SAFE > 0 and the given tmpdir is tainted, it uses
-  # /tmp. (Note that ENV values are tainted by default)
+  # The +basename+ parameter is used to determine the name of the
+  # temporary file. You can either pass a String or an Array with
+  # 2 String elements. In the former form, the temporary file's base
+  # name will begin with the given string. In the latter form,
+  # the temporary file's base name will begin with the array's first
+  # element, and end with the second element. For example:
+  #
+  #   file = Tempfile.new('hello')
+  #   file.path  # => something like: "/tmp/foo????-????-????9382--0"
+  #   
+  #   # Use the Array form to enforce an extension in the filename:
+  #   file = Tempfile.new(['hello', '.jpg'])
+  #   file.path  # => something like: "/tmp/foo????-????-????9382--0.jpg"
+  #
+  # The temporary file will be placed in the directory as specified
+  # by the +tmpdir+ parameter. By default, this is +Dir.tmpdir+.
+  # When $SAFE > 0 and the given +tmpdir+ is tainted, it uses
+  # '/tmp' as the temporary directory. Please note that ENV values
+  # are tainted by default, and +Dir.tmpdir+'s return value might
+  # come from environment variables (e.g. <tt>$TMPDIR</tt>).
+  #
+  #   file = Tempfile.new('hello', '/home/aisaka')
+  #   file.path  # => something like: "/home/aisaka/foo????-????-????9382--0"
+  #
+  # You can also pass an options hash. Under the hood, Tempfile creates
+  # the temporary file using +File.open+. These options will be passed to
+  # +File.open+. This is mostly useful for specifying encoding
+  # options, e.g.:
+  #
+  #   Tempfile.new('hello', '/home/aisaka', :encoding => 'ascii-8bit')
+  #   
+  #   # You can also omit the 'tmpdir' parameter:
+  #   Tempfile.new('hello', :encoding => 'ascii-8bit')
+  #
+  # === Exceptions
+  # 
+  # Under rare circumstances, this constructor can raise an instance of
+  # Tempfile::CreationError. This could happen if a large number
+  # of threads or processes are simultaneously trying to create temp files
+  # and stepping on each others' toes. If Tempfile.new cannot find
+  # a unique filename within a limited number of tries, then it will raise
+  # this exception.
   def initialize(basename, *rest)
     # I wish keyword argument settled soon.
     if opts = Hash.try_convert(rest[-1])
@@ -108,8 +210,9 @@
   end
   protected :_close
 
-  #Closes the file.  If the optional flag is true, unlinks the file
-  # after closing.
+  # Closes the file. If +unlink_now+ is true, then the file will be unlinked
+  # (deleted) after closing. Of course, you can choose to later call #unlink
+  # if you do not unlink it now.
   #
   # If you don't explicitly unlink the temporary file, the removal
   # will be delayed until the object is finalized.
@@ -121,18 +224,47 @@
     end
   end
 
-  # Closes and unlinks the file.
-  # Has the same effect as called <tt>close(true)</tt>.
+  # Closes and unlinks (deletes) the file. Has the same effect as called
+  # <tt>close(true)</tt>.
   def close!
     _close
     unlink
     ObjectSpace.undefine_finalizer(self)
   end
 
-  # Unlinks the file.  On UNIX-like systems, it is often a good idea
-  # to unlink a temporary file immediately after creating and opening
-  # it, because it leaves other programs zero chance to access the
-  # file.
+  # Unlinks (deletes) the file from the filesystem. One should always unlink
+  # the file after using it, as is explained in the "Explicit close" good
+  # practice section in the Tempfile overview:
+  #
+  #   file = Tempfile.new('foo)
+  #   begin
+  #      ...do something with file...
+  #   ensure
+  #      file.close
+  #      file.unlink   # deletes the temp file
+  #   end
+  #
+  # === Unlink-before-close
+  #
+  # On POSIX systems it's possible to unlink a file before closing it. This
+  # practice is explained in detail in the Tempfile overview (section
+  # "Unlink after creation"); please refer there for more information.
+  #
+  # However, unlink-before-close may not be supported on non-POSIX operating
+  # systems. Microsoft Windows is the most notable case: unlinking a non-closed
+  # file will result in an error, which this method will silently ignore. If
+  # you want to practice unlink-before-close whenever possible, then you should
+  # write code like this:
+  #
+  #   file = Tempfile.new('foo')
+  #   file.unlink   # On Windows this silently fails.
+  #   begin
+  #      ... do something with file ...
+  #   ensure
+  #      file.close!   # Closes the file handle. If the file wasn't unlinked
+  #                    # because #unlink failed, then this method will attempt
+  #                    # to do so again.
+  #   end
   def unlink
     # keep this order for thread safeness
     return unless @tmpname
@@ -190,11 +322,28 @@
       }
     end
 
-    # If no block is given, this is a synonym for new().
+    # Creates a new Tempfile.
     #
-    # If a block is given, it will be passed tempfile as an argument,
-    # and the tempfile will automatically be closed when the block
-    # terminates.  The call returns the value of the block.
+    # If no block is given, this is a synonym for Tempfile.new.
+    #
+    # If a block is given, then a Tempfile object will be constructed,
+    # and the block is run with said object as argument. The Tempfile
+    # oject will be automatically closed after the block terminates.
+    # The call returns the value of the block.
+    #
+    # In any case, all arguments (+*args+) will be passed to Tempfile.new.
+    #
+    #   Tempfile.open('foo', '/home/temp') do |f|
+    #      ... do something with f ...
+    #   end
+    #   
+    #   # Equivalent:
+    #   f = Tempfile.open('foo', '/home/temp')
+    #   begin
+    #      ... do something with f ...
+    #   ensure
+    #      f.close
+    #   end
     def open(*args)
       tempfile = new(*args)
 

Property changes on: lib/tempfile.rb
___________________________________________________________________
Name: svn:executable
   + *


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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