From 589f1c1d55433cbff3e8c8dab471fa8f88371ae8 Mon Sep 17 00:00:00 2001 From: Burdette Lamar Date: Fri, 6 May 2022 13:07:49 -0500 Subject: [PATCH] [ruby/tempfile] Enhanced RDoc for ::new and ::create (https://github.com/ruby/tempfile/pull/10) https://github.com/ruby/tempfile/commit/a5e53aa82a --- lib/tempfile.rb | 145 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 97 insertions(+), 48 deletions(-) diff --git a/lib/tempfile.rb b/lib/tempfile.rb index c1b696c4cf..8a6bcc3e14 100644 --- a/lib/tempfile.rb +++ b/lib/tempfile.rb @@ -87,50 +87,64 @@ require 'tmpdir' # same Tempfile object from multiple threads then you should protect it with a # mutex. class Tempfile < DelegateClass(File) - # Creates a temporary file with permissions 0600 (= only readable and - # writable by the owner) and opens it with mode "w+". + + # Creates a file in the underlying file system; + # returns a new \Tempfile object based on that file. # - # It is recommended to use Tempfile.create { ... } instead when possible, - # because that method avoids the cost of delegation and does not rely on a - # finalizer to close and unlink the file, which is unreliable. + # If possible, consider instead using Tempfile.create, which: # - # 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: + # - Avoids the performance cost of delegation, + # incurred when Tempfile.new calls its superclass DelegateClass(File). + # - Does not rely on a finalizer to close and unlink the file, + # which can be unreliable. # - # file = Tempfile.new('hello') - # file.path # => something like: "/tmp/hello2843-8392-92849382--0" + # Creates and returns file whose: # - # # Use the Array form to enforce an extension in the filename: - # file = Tempfile.new(['hello', '.jpg']) - # file.path # => something like: "/tmp/hello2843-8392-92849382--0.jpg" + # - Class is \Tempfile (not \File, as in Tempfile.create). + # - Directory is the system temporary directory (system-dependent). + # - Generated filename is unique in that directory. + # - Permissions are 0600; + # see {File Permissions}[https://docs.ruby-lang.org/en/master/File.html#label-File+Permissions]. + # - Mode is 'w+' (read/write mode, positioned at the end). # - # The temporary file will be placed in the directory as specified - # by the +tmpdir+ parameter. By default, this is +Dir.tmpdir+. + # The underlying file is removed when the \Tempfile object dies + # and is reclaimed by the garbage collector. # - # file = Tempfile.new('hello', '/home/aisaka') - # file.path # => something like: "/home/aisaka/hello2843-8392-92849382--0" + # Example: # - # 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.: + # f = Tempfile.new # => # + # f.class # => Tempfile + # f.path # => "/tmp/20220505-17839-1s0kt30" + # f.stat.mode.to_s(8) # => "100600" + # File.exist?(f.path) # => true + # File.unlink(f.path) # + # File.exist?(f.path) # => false # - # Tempfile.new('hello', '/home/aisaka', encoding: 'ascii-8bit') + # Argument +basename+, if given, may be one of: # - # # You can also omit the 'tmpdir' parameter: - # Tempfile.new('hello', encoding: 'ascii-8bit') + # - A string: the generated filename begins with +basename+: # - # Note: +mode+ keyword argument, as accepted by Tempfile, can only be - # numeric, combination of the modes defined in File::Constants. + # Tempfile.new('foo') # => # # - # === Exceptions + # - An array of two strings [prefix, suffix]: + # the generated filename begins with +prefix+ and ends with +suffix+: + # + # Tempfile.new(%w/foo .jpg/) # => # + # + # With arguments +basename+ and +tmpdir+, the file is created in directory +tmpdir+: + # + # Tempfile.new('foo', '.') # => # + # + # Keyword arguments +mode+ and +options+ are passed directly to method + # {File.open}[https://docs.ruby-lang.org/en/master/File.html#method-c-open]: + # + # - The value given with +mode+ must be an integer, + # and may be expressed as the logical OR of constants defined in + # {File::Constants}[https://docs.ruby-lang.org/en/master/File/Constants.html]. + # - For +options+, see {Open Options}[https://docs.ruby-lang.org/en/master/IO.html#class-IO-label-Open+Options]. + # + # Related: Tempfile.create. # - # 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) warn "Tempfile.new doesn't call the given block.", uplevel: 1 if block_given? @@ -325,26 +339,61 @@ class Tempfile < DelegateClass(File) end end -# Creates a temporary file as a usual File object (not a Tempfile). -# It does not use finalizer and delegation, which makes it more efficient and reliable. +# Creates a file in the underlying file system; +# returns a new \File object based on that file. # -# If no block is given, this is similar to Tempfile.new except -# creating File instead of Tempfile. In that case, the created file is -# not removed automatically. You should use File.unlink to remove it. +# With no block given and no arguments, creates and returns file whose: # -# If a block is given, then a File object will be constructed, -# and the block is invoked with the object as the argument. -# The File object will be automatically closed and -# the temporary file is removed after the block terminates, -# releasing all resources that the block created. -# The call returns the value of the block. +# - Class is {File}[https://docs.ruby-lang.org/en/master/File.html] (not \Tempfile). +# - Directory is the system temporary directory (system-dependent). +# - Generated filename is unique in that directory. +# - Permissions are 0600; +# see {File Permissions}[https://docs.ruby-lang.org/en/master/File.html#label-File+Permissions]. +# - Mode is 'w+' (read/write mode, positioned at the end). # -# In any case, all arguments (+basename+, +tmpdir+, +mode+, and -# **options) will be treated the same as for Tempfile.new. +# With no block, the file is not removed automatically, +# and so should be explicitly removed. # -# Tempfile.create('foo', '/home/temp') do |f| -# # ... do something with f ... -# end +# Example: +# +# f = Tempfile.create # => # +# f.class # => File +# f.path # => "/tmp/20220505-9795-17ky6f6" +# f.stat.mode.to_s(8) # => "100600" +# File.exist?(f.path) # => true +# File.unlink(f.path) +# File.exist?(f.path) # => false +# +# Argument +basename+, if given, may be one of: +# +# - A string: the generated filename begins with +basename+: +# +# Tempfile.create('foo') # => # +# +# - An array of two strings [prefix, suffix]: +# the generated filename begins with +prefix+ and ends with +suffix+: +# +# Tempfile.create(%w/foo .jpg/) # => # +# +# With arguments +basename+ and +tmpdir+, the file is created in directory +tmpdir+: +# +# Tempfile.create('foo', '.') # => # +# +# Keyword arguments +mode+ and +options+ are passed directly to method +# {File.open}[https://docs.ruby-lang.org/en/master/File.html#method-c-open]: +# +# - The value given with +mode+ must be an integer, +# and may be expressed as the logical OR of constants defined in +# {File::Constants}[https://docs.ruby-lang.org/en/master/File/Constants.html]. +# - For +options+, see {Open Options}[https://docs.ruby-lang.org/en/master/IO.html#class-IO-label-Open+Options]. +# +# With a block given, creates the file as above, passes it to the block, +# and returns the block's value; +# before the return, the file object is closed and the underlying file is removed: +# +# Tempfile.create {|file| file.path } # => "/tmp/20220505-9795-rkists" +# +# Related: Tempfile.new. # def Tempfile.create(basename="", tmpdir=nil, mode: 0, **options) tmpfile = nil