core/kernel.rbs in rbs-3.3.2 vs core/kernel.rbs in rbs-3.4.0.pre.1
- old
+ new
@@ -360,30 +360,68 @@
#
def self?.srand: (?int number) -> Integer
# <!--
# rdoc-file=process.c
- # - Kernel.fork [{ block }] -> integer or nil
- # - Process.fork [{ block }] -> integer or nil
+ # - Process.fork { ... } -> integer or nil
+ # - Process.fork -> integer or nil
# -->
- # Creates a subprocess. If a block is specified, that block is run in the
- # subprocess, and the subprocess terminates with a status of zero. Otherwise,
- # the `fork` call returns twice, once in the parent, returning the process ID of
- # the child, and once in the child, returning *nil*. The child process can exit
- # using Kernel.exit! to avoid running any `at_exit` functions. The parent
- # process should use Process.wait to collect the termination statuses of its
- # children or use Process.detach to register disinterest in their status;
- # otherwise, the operating system may accumulate zombie processes.
+ # Creates a child process.
#
- # The thread calling fork is the only thread in the created child process. fork
- # doesn't copy other threads.
+ # With a block given, runs the block in the child process; on block exit, the
+ # child terminates with a status of zero:
#
- # If fork is not usable, Process.respond_to?(:fork) returns false.
+ # puts "Before the fork: #{Process.pid}"
+ # fork do
+ # puts "In the child process: #{Process.pid}"
+ # end # => 382141
+ # puts "After the fork: #{Process.pid}"
#
- # Note that fork(2) is not available on some platforms like Windows and NetBSD
- # 4. Therefore you should use spawn() instead of fork().
+ # Output:
#
+ # Before the fork: 420496
+ # After the fork: 420496
+ # In the child process: 420520
+ #
+ # With no block given, the `fork` call returns twice:
+ #
+ # * Once in the parent process, returning the pid of the child process.
+ # * Once in the child process, returning `nil`.
+ #
+ #
+ # Example:
+ #
+ # puts "This is the first line before the fork (pid #{Process.pid})"
+ # puts fork
+ # puts "This is the second line after the fork (pid #{Process.pid})"
+ #
+ # Output:
+ #
+ # This is the first line before the fork (pid 420199)
+ # 420223
+ # This is the second line after the fork (pid 420199)
+ #
+ # This is the second line after the fork (pid 420223)
+ #
+ # In either case, the child process may exit using Kernel.exit! to avoid the
+ # call to Kernel#at_exit.
+ #
+ # To avoid zombie processes, the parent process should call either:
+ #
+ # * Process.wait, to collect the termination statuses of its children.
+ # * Process.detach, to register disinterest in their status.
+ #
+ #
+ # The thread calling `fork` is the only thread in the created child process;
+ # `fork` doesn't copy other threads.
+ #
+ # Note that method `fork` is available on some platforms, but not on others:
+ #
+ # Process.respond_to?(:fork) # => true # Would be false on some.
+ #
+ # If not, you may use ::spawn instead of `fork`.
+ #
def self?.fork: () -> Integer?
| () { () -> void } -> Integer
# <!--
# rdoc-file=object.c
@@ -405,44 +443,58 @@
| [T] (array[T] | _ToA[T] array_like) -> Array[T]
| [T] (T ele) -> [T]
# <!--
# rdoc-file=complex.c
- # - Complex(x[, y], exception: true) -> numeric or nil
+ # - Complex(abs, arg = 0, exception: true) -> complex or nil
+ # - Complex(s, exception: true) -> complex or nil
# -->
- # Returns x+i*y;
+ # Returns a new Complex object if the arguments are valid; otherwise raises an
+ # exception if `exception` is `true`; otherwise returns `nil`.
#
- # Complex(1, 2) #=> (1+2i)
- # Complex('1+2i') #=> (1+2i)
- # Complex(nil) #=> TypeError
- # Complex(1, nil) #=> TypeError
+ # With Numeric argument `abs`, returns `Complex.rect(abs, arg)` if the arguments
+ # are valid.
#
- # Complex(1, nil, exception: false) #=> nil
- # Complex('1+2', exception: false) #=> nil
+ # With string argument `s`, returns a new Complex object if the argument is
+ # valid; the string may have:
#
- # Syntax of string form:
+ # * One or two numeric substrings, each of which specifies a Complex, Float,
+ # Integer, Numeric, or Rational value, specifying [rectangular
+ # coordinates](rdoc-ref:Complex@Rectangular+Coordinates):
#
- # string form = extra spaces , complex , extra spaces ;
- # complex = real part | [ sign ] , imaginary part
- # | real part , sign , imaginary part
- # | rational , "@" , rational ;
- # real part = rational ;
- # imaginary part = imaginary unit | unsigned rational , imaginary unit ;
- # rational = [ sign ] , unsigned rational ;
- # unsigned rational = numerator | numerator , "/" , denominator ;
- # numerator = integer part | fractional part | integer part , fractional part ;
- # denominator = digits ;
- # integer part = digits ;
- # fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
- # imaginary unit = "i" | "I" | "j" | "J" ;
- # sign = "-" | "+" ;
- # digits = digit , { digit | "_" , digit };
- # digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
- # extra spaces = ? \s* ? ;
+ # * Sign-separated real and imaginary numeric substrings (with trailing
+ # character `'i'`):
#
- # See String#to_c.
+ # Complex('1+2i') # => (1+2i)
+ # Complex('+1+2i') # => (1+2i)
+ # Complex('+1-2i') # => (1-2i)
+ # Complex('-1+2i') # => (-1+2i)
+ # Complex('-1-2i') # => (-1-2i)
#
+ # * Real-only numeric string (without trailing character `'i'`):
+ #
+ # Complex('1') # => (1+0i)
+ # Complex('+1') # => (1+0i)
+ # Complex('-1') # => (-1+0i)
+ #
+ # * Imaginary-only numeric string (with trailing character `'i'`):
+ #
+ # Complex('1i') # => (0+1i)
+ # Complex('+1i') # => (0+1i)
+ # Complex('-1i') # => (0-1i)
+ #
+ #
+ # * At-sign separated real and imaginary rational substrings, each of which
+ # specifies a Rational value, specifying [polar
+ # coordinates](rdoc-ref:Complex@Polar+Coordinates):
+ #
+ # Complex('1/2@3/4') # => (0.36584443443691045+0.34081938001166706i)
+ # Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i)
+ # Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i)
+ # Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i)
+ # Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i)
+ #
def self?.Complex: (_ToC complex_like, ?exception: true) -> Complex
| (_ToC complex_like, exception: bool) -> Complex?
| (Numeric | String real, ?Numeric | String imag, ?exception: true) -> Complex
| (Numeric | String real, ?Numeric | String imag, exception: bool) -> Complex?
| (untyped, ?untyped, ?exception: bool) -> Complex?
@@ -491,11 +543,11 @@
#
def self?.Hash: [K, V] (nil | [] _empty) -> Hash[K, V]
| [K, V] (hash[K, V] hash_like) -> Hash[K, V]
# <!--
- # rdoc-file=object.c
+ # rdoc-file=kernel.rb
# - Integer(object, base = 0, exception: true) -> integer or nil
# -->
# Returns an integer converted from `object`.
#
# Tries to convert `object` to an integer using `to_int` first and `to_i`
@@ -509,11 +561,11 @@
#
# Integer(1) # => 1
# Integer(-1) # => -1
#
# With floating-point argument `object` given, returns `object` truncated to an
- # intger:
+ # integer:
#
# Integer(1.9) # => 1 # Rounds toward zero.
# Integer(-1.9) # => -1 # Rounds toward zero.
#
# #### string objects
@@ -698,16 +750,18 @@
def self?.`: (String arg0) -> String
# <!--
# rdoc-file=process.c
# - abort
- # - Kernel::abort([msg])
- # - Process.abort([msg])
+ # - Process.abort(msg = nil)
# -->
- # Terminate execution immediately, effectively by calling `Kernel.exit(false)`.
- # If *msg* is given, it is written to STDERR prior to terminating.
+ # Terminates execution immediately, effectively by calling `Kernel.exit(false)`.
#
+ # If string argument `msg` is given, it is written to STDERR prior to
+ # termination; otherwise, if an exception was raised, prints its message and
+ # backtrace.
+ #
def self?.abort: (?string msg) -> bot
# <!--
# rdoc-file=eval_jump.c
# - at_exit { block } -> proc
@@ -757,72 +811,106 @@
# <!--
# rdoc-file=proc.c
# - binding -> a_binding
# -->
- # Returns a `Binding` object, describing the variable and method bindings at the
- # point of call. This object can be used when calling `eval` to execute the
- # evaluated command in this environment. See also the description of class
- # `Binding`.
+ # Returns a Binding object, describing the variable and method bindings at the
+ # point of call. This object can be used when calling Binding#eval to execute
+ # the evaluated command in this environment, or extracting its local variables.
#
- # def get_binding(param)
- # binding
+ # class User
+ # def initialize(name, position)
+ # @name = name
+ # @position = position
+ # end
+ #
+ # def get_binding
+ # binding
+ # end
# end
- # b = get_binding("hello")
- # eval("param", b) #=> "hello"
#
+ # user = User.new('Joan', 'manager')
+ # template = '{name: @name, position: @position}'
+ #
+ # # evaluate template in context of the object
+ # eval(template, user.get_binding)
+ # #=> {:name=>"Joan", :position=>"manager"}
+ #
+ # Binding#local_variable_get can be used to access the variables whose names are
+ # reserved Ruby keywords:
+ #
+ # # This is valid parameter declaration, but `if` parameter can't
+ # # be accessed by name, because it is a reserved word.
+ # def validate(field, validation, if: nil)
+ # condition = binding.local_variable_get('if')
+ # return unless condition
+ #
+ # # ...Some implementation ...
+ # end
+ #
+ # validate(:name, :empty?, if: false) # skips validation
+ # validate(:name, :empty?, if: true) # performs validation
+ #
def self?.binding: () -> Binding
# <!--
# rdoc-file=process.c
- # - exit(status=true)
- # - Kernel::exit(status=true)
- # - Process::exit(status=true)
+ # - exit(status = true)
+ # - Process.exit(status = true)
# -->
- # Initiates the termination of the Ruby script by raising the SystemExit
- # exception. This exception may be caught. The optional parameter is used to
- # return a status code to the invoking environment. `true` and `FALSE` of
- # *status* means success and failure respectively. The interpretation of other
- # integer values are system dependent.
+ # Initiates termination of the Ruby script by raising SystemExit; the exception
+ # may be caught. Returns exit status `status` to the underlying operating
+ # system.
#
+ # Values `true` and `false` for argument `status` indicate, respectively,
+ # success and failure; The meanings of integer values are system-dependent.
+ #
+ # Example:
+ #
# begin
# exit
- # puts "never get here"
+ # puts 'Never get here.'
# rescue SystemExit
- # puts "rescued a SystemExit exception"
+ # puts 'Rescued a SystemExit exception.'
# end
- # puts "after begin block"
+ # puts 'After begin block.'
#
- # *produces:*
+ # Output:
#
- # rescued a SystemExit exception
- # after begin block
+ # Rescued a SystemExit exception.
+ # After begin block.
#
- # Just prior to termination, Ruby executes any `at_exit` functions (see
- # Kernel::at_exit) and runs any object finalizers (see
+ # Just prior to final termination, Ruby executes any at-exit procedures (see
+ # Kernel::at_exit) and any object finalizers (see
# ObjectSpace::define_finalizer).
#
- # at_exit { puts "at_exit function" }
- # ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
+ # Example:
+ #
+ # at_exit { puts 'In at_exit function.' }
+ # ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' })
# exit
#
- # *produces:*
+ # Output:
#
- # at_exit function
- # in finalizer
+ # In at_exit function.
+ # In finalizer.
#
def self?.exit: (?int | bool status) -> bot
# <!--
# rdoc-file=process.c
- # - Process.exit!(status=false)
+ # - exit!(status = false)
+ # - Process.exit!(status = false)
# -->
- # Exits the process immediately. No exit handlers are run. *status* is returned
- # to the underlying system as the exit status.
+ # Exits the process immediately; no exit handlers are called. Returns exit
+ # status `status` to the underlying operating system.
#
# Process.exit!(true)
#
+ # Values `true` and `false` for argument `status` indicate, respectively,
+ # success and failure; The meanings of integer values are system-dependent.
+ #
def self?.exit!: (?int | bool status) -> bot
# <!-- rdoc-file=eval.c -->
# With no arguments, raises the exception in `$!` or raises a RuntimeError if
# `$!` is `nil`. With a single `String` argument, raises a `RuntimeError` with
@@ -880,12 +968,10 @@
# Returns the string resulting from formatting `objects` into `format_string`.
#
# For details on `format_string`, see [Format
# Specifications](rdoc-ref:format_specifications.rdoc).
#
- # Kernel#format is an alias for Kernel#sprintf.
- #
def self?.format: (String format, *untyped args) -> String
# <!--
# rdoc-file=object.c
# - sprintf(format_string *objects) -> string
@@ -893,12 +979,10 @@
# Returns the string resulting from formatting `objects` into `format_string`.
#
# For details on `format_string`, see [Format
# Specifications](rdoc-ref:format_specifications.rdoc).
#
- # Kernel#format is an alias for Kernel#sprintf.
- #
alias sprintf format
alias self.sprintf self.format
# <!--
@@ -945,11 +1029,11 @@
#
def self?.global_variables: () -> ::Array[Symbol]
# <!--
# rdoc-file=load.c
- # - load(file, wrap = false)
+ # - load(filename, wrap=false) -> true
# -->
# Loads and executes the Ruby program in the file *filename*.
#
# If the filename is an absolute path (e.g. starts with '/'), the file will be
# loaded directly using the absolute path.
@@ -973,11 +1057,11 @@
# in the loaded file be propagated to the loading environment.
#
def self?.load: (String filename, ?Module | bool) -> bool
# <!--
- # rdoc-file=vm_eval.c
+ # rdoc-file=kernel.rb
# - loop { block }
# - loop -> an_enumerator
# -->
# Repeatedly executes the block.
#
@@ -1009,26 +1093,15 @@
# <!--
# rdoc-file=io.c
# - open(path, mode = 'r', perm = 0666, **opts) -> io or nil
# - open(path, mode = 'r', perm = 0666, **opts) {|io| ... } -> obj
# -->
- # Creates an IO object connected to the given stream, file, or subprocess.
+ # Creates an IO object connected to the given file.
#
- # Required string argument `path` determines which of the following occurs:
+ # This method has potential security vulnerabilities if called with untrusted
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
#
- # * The file at the specified `path` is opened.
- # * The process forks.
- # * A subprocess is created.
- #
- #
- # Each of these is detailed below.
- #
- # **File Opened**
- #
- # If `path` does *not* start with a pipe character (`'|'`), a file stream is
- # opened with `File.open(path, mode, perm, **opts)`.
- #
# With no block given, file stream is returned:
#
# open('t.txt') # => #<File:t.txt>
#
# With a block given, calls the block with the open file stream, then closes the
@@ -1040,70 +1113,10 @@
#
# #<File:t.txt>
#
# See File.open for details.
#
- # **Process Forked**
- #
- # If `path` is the 2-character string `'|-'`, the process forks and the child
- # process is connected to the parent.
- #
- # With no block given:
- #
- # io = open('|-')
- # if io
- # $stderr.puts "In parent, child pid is #{io.pid}."
- # else
- # $stderr.puts "In child, pid is #{$$}."
- # end
- #
- # Output:
- #
- # In parent, child pid is 27903.
- # In child, pid is 27903.
- #
- # With a block given:
- #
- # open('|-') do |io|
- # if io
- # $stderr.puts "In parent, child pid is #{io.pid}."
- # else
- # $stderr.puts "In child, pid is #{$$}."
- # end
- # end
- #
- # Output:
- #
- # In parent, child pid is 28427.
- # In child, pid is 28427.
- #
- # **Subprocess Created**
- #
- # If `path` is `'|command'` (`'command' != '-'`), a new subprocess runs the
- # command; its open stream is returned. Note that the command may be processed
- # by shell if it contains shell metacharacters.
- #
- # With no block given:
- #
- # io = open('|echo "Hi!"') # => #<IO:fd 12>
- # print io.gets
- # io.close
- #
- # Output:
- #
- # "Hi!"
- #
- # With a block given, calls the block with the stream, then closes the stream:
- #
- # open('|echo "Hi!"') do |io|
- # print io.gets
- # end
- #
- # Output:
- #
- # "Hi!"
- #
def self?.open: (String name, ?String mode, ?Integer perm) -> IO?
| [T] (String name, ?String mode, ?Integer perm) { (IO) -> T } -> T
# <!--
# rdoc-file=io.c
@@ -1253,10 +1266,14 @@
# Output:
#
# 0..4
# [0..4, 0..4, 0..4]
#
+ # Kernel#p is designed for debugging purposes. Ruby implementations may define
+ # Kernel#p to be uninterruptible in whole or in part. On CRuby, Kernel#p's
+ # writing of data is uninterruptible.
+ #
def self?.p: [T < _Inspect] (T arg0) -> T
| (_Inspect arg0, _Inspect arg1, *_Inspect rest) -> Array[_Inspect]
| () -> nil
# <!--
@@ -1397,11 +1414,11 @@
#
def self?.require: (String path) -> bool
# <!--
# rdoc-file=load.c
- # - require_relative(file)
+ # - require_relative(string) -> true or false
# -->
# Ruby tries to load the library named *string* relative to the directory
# containing the requiring file. If the file does not exist a LoadError is
# raised. Returns `true` if the file was loaded and `false` if the file was
# already loaded before.
@@ -1549,23 +1566,21 @@
#
def self?.select: (::Array[IO] read, ?::Array[IO] write, ?::Array[IO] error, ?Integer timeout) -> ::Array[String]
# <!--
# rdoc-file=process.c
- # - sleep([duration]) -> integer
+ # - sleep(secs = nil) -> slept_secs
# -->
- # Suspends the current thread for *duration* seconds (which may be any number,
- # including a `Float` with fractional seconds). Returns the actual number of
- # seconds slept (rounded), which may be less than that asked for if another
- # thread calls Thread#run. Called without an argument, sleep() will sleep
- # forever.
+ # Suspends execution of the current thread for the number of seconds specified
+ # by numeric argument `secs`, or forever if `secs` is `nil`; returns the integer
+ # number of seconds suspended (rounded).
#
- # Time.new #=> 2008-03-08 19:56:19 +0900
- # sleep 1.2 #=> 1
- # Time.new #=> 2008-03-08 19:56:20 +0900
- # sleep 1.9 #=> 2
- # Time.new #=> 2008-03-08 19:56:22 +0900
+ # Time.new # => 2008-03-08 19:56:19 +0900
+ # sleep 1.2 # => 1
+ # Time.new # => 2008-03-08 19:56:20 +0900
+ # sleep 1.9 # => 2
+ # Time.new # => 2008-03-08 19:56:22 +0900
#
def self?.sleep: (?nil) -> bot
| (Integer | Float | _Divmod duration) -> Integer
interface _Divmod
@@ -1674,35 +1689,35 @@
# If warnings have been disabled (for example with the `-W0` flag), does
# nothing. Otherwise, converts each of the messages to strings, appends a
# newline character to the string if the string does not end in a newline, and
# calls Warning.warn with the string.
#
- # warn("warning 1", "warning 2")
+ # warn("warning 1", "warning 2")
#
- # <em>produces:</em>
+ # *produces:*
#
- # warning 1
- # warning 2
+ # warning 1
+ # warning 2
#
# If the `uplevel` keyword argument is given, the string will be prepended with
# information for the given caller frame in the same format used by the
# `rb_warn` C function.
#
- # # In baz.rb
- # def foo
- # warn("invalid call to foo", uplevel: 1)
- # end
+ # # In baz.rb
+ # def foo
+ # warn("invalid call to foo", uplevel: 1)
+ # end
#
- # def bar
- # foo
- # end
+ # def bar
+ # foo
+ # end
#
- # bar
+ # bar
#
- # <em>produces:</em>
+ # *produces:*
#
- # baz.rb:6: warning: invalid call to foo
+ # baz.rb:6: warning: invalid call to foo
#
# If `category` keyword argument is given, passes the category to
# `Warning.warn`. The category given must be be one of the following
# categories:
#
@@ -1714,387 +1729,334 @@
#
def self?.warn: (*_ToS msg, ?uplevel: int?, ?category: Warning::category?) -> nil
# <!--
# rdoc-file=process.c
- # - exec([env,] command... [,options])
+ # - exec([env, ] command_line, options = {})
+ # - exec([env, ] exe_path, *args, options = {})
# -->
- # Replaces the current process by running the given external *command*, which
- # can take one of the following forms:
+ # Replaces the current process by doing one of the following:
#
- # `exec(commandline)`
- # : command line string which is passed to the standard shell
- # `exec(cmdname, arg1, ...)`
- # : command name and one or more arguments (no shell)
- # `exec([cmdname, argv0], arg1, ...)`
- # : command name, `argv[0]` and zero or more arguments (no shell)
+ # * Passing string `command_line` to the shell.
+ # * Invoking the executable at `exe_path`.
#
#
- # In the first form, the string is taken as a command line that is subject to
- # shell expansion before being executed.
+ # This method has potential security vulnerabilities if called with untrusted
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
#
- # The standard shell always means `"/bin/sh"` on Unix-like systems, otherwise,
- # `ENV["RUBYSHELL"]` or `ENV["COMSPEC"]` on Windows and similar. The command is
- # passed as an argument to the `"-c"` switch to the shell, except in the case of
- # `COMSPEC`.
+ # The new process is created using the [exec system
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/e
+ # xecve.html); it may inherit some of its environment from the calling program
+ # (possibly including open file descriptors).
#
- # If the string from the first form (`exec("command")`) follows these simple
- # rules:
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
#
- # * no meta characters,
- # * not starting with shell reserved word or special built-in,
+ # Argument `options` is a hash of options for the new process; see [Execution
+ # Options](rdoc-ref:Process@Execution+Options).
#
+ # The first required argument is one of the following:
#
- # Ruby invokes the command directly without shell.
+ # * `command_line` if it is a string, and if it begins with a shell reserved
+ # word or special built-in, or if it contains one or more meta characters.
+ # * `exe_path` otherwise.
#
- # You can force shell invocation by adding ";" to the string (because ";" is a
- # meta character).
#
- # Note that this behavior is observable by pid obtained (return value of spawn()
- # and IO#pid for IO.popen) is the pid of the invoked command, not shell.
+ # **Argument `command_line`**
#
- # In the second form (`exec("command1", "arg1", ...)`), the first is taken as a
- # command name and the rest are passed as parameters to command with no shell
- # expansion.
+ # String argument `command_line` is a command line to be passed to a shell; it
+ # must begin with a shell reserved word, begin with a special built-in, or
+ # contain meta characters:
#
- # In the third form (`exec(["command", "argv0"], "arg1", ...)`), starting a
- # two-element array at the beginning of the command, the first element is the
- # command to be executed, and the second argument is used as the `argv[0]`
- # value, which may show up in process listings.
+ # exec('if true; then echo "Foo"; fi') # Shell reserved word.
+ # exec('echo') # Built-in.
+ # exec('date > date.tmp') # Contains meta character.
#
- # In order to execute the command, one of the `exec(2)` system calls are used,
- # so the running command may inherit some of the environment of the original
- # program (including open file descriptors).
+ # The command line may also contain arguments and options for the command:
#
- # This behavior is modified by the given `env` and `options` parameters. See
- # ::spawn for details.
+ # exec('echo "Foo"')
#
- # If the command fails to execute (typically Errno::ENOENT when it was not
- # found) a SystemCallError exception is raised.
+ # Output:
#
- # This method modifies process attributes according to given `options` before
- # `exec(2)` system call. See ::spawn for more details about the given `options`.
+ # Foo
#
- # The modified attributes may be retained when `exec(2)` system call fails.
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
+ # shell.
#
- # For example, hard resource limits are not restorable.
+ # Raises an exception if the new process could not execute.
#
- # Consider to create a child process using ::spawn or Kernel#system if this is
- # not acceptable.
+ # **Argument `exe_path`**
#
- # exec "echo *" # echoes list of files in current directory
- # # never get here
+ # Argument `exe_path` is one of the following:
#
- # exec "echo", "*" # echoes an asterisk
- # # never get here
+ # * The string path to an executable to be called.
+ # * A 2-element array containing the path to an executable and the string to
+ # be used as the name of the executing process.
#
+ #
+ # Example:
+ #
+ # exec('/usr/bin/date')
+ #
+ # Output:
+ #
+ # Sat Aug 26 09:38:00 AM CDT 2023
+ #
+ # Ruby invokes the executable directly, with no shell and no shell expansion:
+ #
+ # exec('doesnt_exist') # Raises Errno::ENOENT
+ #
+ # If one or more `args` is given, each is an argument or option to be passed to
+ # the executable:
+ #
+ # exec('echo', 'C*')
+ # exec('echo', 'hello', 'world')
+ #
+ # Output:
+ #
+ # C*
+ # hello world
+ #
+ # Raises an exception if the new process could not execute.
+ #
def self?.exec: (String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> bot
| (Hash[string, string?] env, String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> bot
type redirect_fd = Integer | :in | :out | :err | IO | String | [ String ] | [ String, string | int ] | [ String, string | int, int ] | [ :child, int ] | :close
# <!--
# rdoc-file=process.c
- # - spawn([env,] command... [,options]) -> pid
- # - Process.spawn([env,] command... [,options]) -> pid
+ # - spawn([env, ] command_line, options = {}) -> pid
+ # - spawn([env, ] exe_path, *args, options = {}) -> pid
# -->
- # spawn executes specified command and return its pid.
+ # Creates a new child process by doing one of the following in that process:
#
- # pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
- # Process.wait pid
+ # * Passing string `command_line` to the shell.
+ # * Invoking the executable at `exe_path`.
#
- # pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
- # Process.wait pid
#
- # This method is similar to Kernel#system but it doesn't wait for the command to
- # finish.
+ # This method has potential security vulnerabilities if called with untrusted
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
#
- # The parent process should use Process.wait to collect the termination status
- # of its child or use Process.detach to register disinterest in their status;
- # otherwise, the operating system may accumulate zombie processes.
+ # Returns the process ID (pid) of the new process, without waiting for it to
+ # complete.
#
- # spawn has bunch of options to specify process attributes:
+ # To avoid zombie processes, the parent process should call either:
#
- # env: hash
- # name => val : set the environment variable
- # name => nil : unset the environment variable
+ # * Process.wait, to collect the termination statuses of its children.
+ # * Process.detach, to register disinterest in their status.
#
- # the keys and the values except for +nil+ must be strings.
- # command...:
- # commandline : command line string which is passed to the standard shell
- # cmdname, arg1, ... : command name and one or more arguments (This form does not use the shell. See below for caveats.)
- # [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
- # options: hash
- # clearing environment variables:
- # :unsetenv_others => true : clear environment variables except specified by env
- # :unsetenv_others => false : don't clear (default)
- # process group:
- # :pgroup => true or 0 : make a new process group
- # :pgroup => pgid : join the specified process group
- # :pgroup => nil : don't change the process group (default)
- # create new process group: Windows only
- # :new_pgroup => true : the new process is the root process of a new process group
- # :new_pgroup => false : don't create a new process group (default)
- # resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
- # :rlimit_resourcename => limit
- # :rlimit_resourcename => [cur_limit, max_limit]
- # umask:
- # :umask => int
- # redirection:
- # key:
- # FD : single file descriptor in child process
- # [FD, FD, ...] : multiple file descriptor in child process
- # value:
- # FD : redirect to the file descriptor in parent process
- # string : redirect to file with open(string, "r" or "w")
- # [string] : redirect to file with open(string, File::RDONLY)
- # [string, open_mode] : redirect to file with open(string, open_mode, 0644)
- # [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
- # [:child, FD] : redirect to the redirected file descriptor
- # :close : close the file descriptor in child process
- # FD is one of follows
- # :in : the file descriptor 0 which is the standard input
- # :out : the file descriptor 1 which is the standard output
- # :err : the file descriptor 2 which is the standard error
- # integer : the file descriptor of specified the integer
- # io : the file descriptor specified as io.fileno
- # file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
- # :close_others => false : inherit
- # current directory:
- # :chdir => str
#
- # The `cmdname, arg1, ...` form does not use the shell. However, on different
- # OSes, different things are provided as built-in commands. An example of this
- # is +'echo'+, which is a built-in on Windows, but is a normal program on Linux
- # and Mac OS X. This means that `Process.spawn 'echo', '%Path%'` will display
- # the contents of the `%Path%` environment variable on Windows, but
- # `Process.spawn 'echo', '$PATH'` prints the literal `$PATH`.
+ # The new process is created using the [exec system
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/e
+ # xecve.html); it may inherit some of its environment from the calling program
+ # (possibly including open file descriptors).
#
- # If a hash is given as `env`, the environment is updated by `env` before
- # `exec(2)` in the child process. If a pair in `env` has nil as the value, the
- # variable is deleted.
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
#
- # # set FOO as BAR and unset BAZ.
- # pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)
+ # Argument `options` is a hash of options for the new process; see [Execution
+ # Options](rdoc-ref:Process@Execution+Options).
#
- # If a hash is given as `options`, it specifies process group, create new
- # process group, resource limit, current directory, umask and redirects for the
- # child process. Also, it can be specified to clear environment variables.
+ # The first required argument is one of the following:
#
- # The `:unsetenv_others` key in `options` specifies to clear environment
- # variables, other than specified by `env`.
+ # * `command_line` if it is a string, and if it begins with a shell reserved
+ # word or special built-in, or if it contains one or more meta characters.
+ # * `exe_path` otherwise.
#
- # pid = spawn(command, :unsetenv_others=>true) # no environment variable
- # pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only
#
- # The `:pgroup` key in `options` specifies a process group. The corresponding
- # value should be true, zero, a positive integer, or nil. true and zero cause
- # the process to be a process leader of a new process group. A non-zero positive
- # integer causes the process to join the provided process group. The default
- # value, nil, causes the process to remain in the same process group.
+ # **Argument `command_line`**
#
- # pid = spawn(command, :pgroup=>true) # process leader
- # pid = spawn(command, :pgroup=>10) # belongs to the process group 10
+ # String argument `command_line` is a command line to be passed to a shell; it
+ # must begin with a shell reserved word, begin with a special built-in, or
+ # contain meta characters:
#
- # The `:new_pgroup` key in `options` specifies to pass
- # `CREATE_NEW_PROCESS_GROUP` flag to `CreateProcessW()` that is Windows API.
- # This option is only for Windows. true means the new process is the root
- # process of the new process group. The new process has CTRL+C disabled. This
- # flag is necessary for `Process.kill(:SIGINT, pid)` on the subprocess.
- # :new_pgroup is false by default.
+ # spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word.
+ # Process.wait # => 798847
+ # spawn('echo') # => 798848 # Built-in.
+ # Process.wait # => 798848
+ # spawn('date > /tmp/date.tmp') # => 798879 # Contains meta character.
+ # Process.wait # => 798849
+ # spawn('date > /nop/date.tmp') # => 798882 # Issues error message.
+ # Process.wait # => 798882
#
- # pid = spawn(command, :new_pgroup=>true) # new process group
- # pid = spawn(command, :new_pgroup=>false) # same process group
+ # The command line may also contain arguments and options for the command:
#
- # The `:rlimit_`*foo* key specifies a resource limit. *foo* should be one of
- # resource types such as `core`. The corresponding value should be an integer or
- # an array which have one or two integers: same as cur_limit and max_limit
- # arguments for Process.setrlimit.
+ # spawn('echo "Foo"') # => 799031
+ # Process.wait # => 799031
#
- # cur, max = Process.getrlimit(:CORE)
- # pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
- # pid = spawn(command, :rlimit_core=>max) # enable core dump
- # pid = spawn(command, :rlimit_core=>0) # never dump core.
+ # Output:
#
- # The `:umask` key in `options` specifies the umask.
+ # Foo
#
- # pid = spawn(command, :umask=>077)
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
+ # shell.
#
- # The :in, :out, :err, an integer, an IO and an array key specifies a
- # redirection. The redirection maps a file descriptor in the child process.
+ # Raises an exception if the new process could not execute.
#
- # For example, stderr can be merged into stdout as follows:
+ # **Argument `exe_path`**
#
- # pid = spawn(command, :err=>:out)
- # pid = spawn(command, 2=>1)
- # pid = spawn(command, STDERR=>:out)
- # pid = spawn(command, STDERR=>STDOUT)
+ # Argument `exe_path` is one of the following:
#
- # The hash keys specifies a file descriptor in the child process started by
- # #spawn. :err, 2 and STDERR specifies the standard error stream (stderr).
+ # * The string path to an executable to be called:
#
- # The hash values specifies a file descriptor in the parent process which
- # invokes #spawn. :out, 1 and STDOUT specifies the standard output stream
- # (stdout).
+ # spawn('/usr/bin/date') # Path to date on Unix-style system.
+ # Process.wait
#
- # In the above example, the standard output in the child process is not
- # specified. So it is inherited from the parent process.
+ # Output:
#
- # The standard input stream (stdin) can be specified by :in, 0 and STDIN.
+ # Thu Aug 31 10:06:48 AM CDT 2023
#
- # A filename can be specified as a hash value.
+ # * A 2-element array containing the path to an executable and the string to
+ # be used as the name of the executing process:
#
- # pid = spawn(command, :in=>"/dev/null") # read mode
- # pid = spawn(command, :out=>"/dev/null") # write mode
- # pid = spawn(command, :err=>"log") # write mode
- # pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
- # pid = spawn(command, 3=>"/dev/null") # read mode
+ # pid = spawn(['sleep', 'Hello!'], '1') # 2-element array.
+ # p `ps -p #{pid} -o command=`
#
- # For stdout and stderr (and combination of them), it is opened in write mode.
- # Otherwise read mode is used.
+ # Output:
#
- # For specifying flags and permission of file creation explicitly, an array is
- # used instead.
+ # "Hello! 1\n"
#
- # pid = spawn(command, :in=>["file"]) # read mode is assumed
- # pid = spawn(command, :in=>["file", "r"])
- # pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
- # pid = spawn(command, :out=>["log", "w", 0600])
- # pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])
#
- # The array specifies a filename, flags and permission. The flags can be a
- # string or an integer. If the flags is omitted or nil, File::RDONLY is assumed.
- # The permission should be an integer. If the permission is omitted or nil, 0644
- # is assumed.
+ # Ruby invokes the executable directly, with no shell and no shell expansion.
#
- # If an array of IOs and integers are specified as a hash key, all the elements
- # are redirected.
+ # If one or more `args` is given, each is an argument or option to be passed to
+ # the executable:
#
- # # stdout and stderr is redirected to log file.
- # # The file "log" is opened just once.
- # pid = spawn(command, [:out, :err]=>["log", "w"])
+ # spawn('echo', 'C*') # => 799392
+ # Process.wait # => 799392
+ # spawn('echo', 'hello', 'world') # => 799393
+ # Process.wait # => 799393
#
- # Another way to merge multiple file descriptors is [:child, fd]. [:child, fd]
- # means the file descriptor in the child process. This is different from fd. For
- # example, :err=>:out means redirecting child stderr to parent stdout. But
- # :err=>[:child, :out] means redirecting child stderr to child stdout. They
- # differ if stdout is redirected in the child process as follows.
+ # Output:
#
- # # stdout and stderr is redirected to log file.
- # # The file "log" is opened just once.
- # pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])
+ # C*
+ # hello world
#
- # [:child, :out] can be used to merge stderr into stdout in IO.popen. In this
- # case, IO.popen redirects stdout to a pipe in the child process and [:child,
- # :out] refers the redirected stdout.
+ # Raises an exception if the new process could not execute.
#
- # io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
- # p io.read #=> "out\nerr\n"
+ def self?.spawn: (String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> Integer
+ | (Hash[string, string?] env, String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> Integer
+
+ # <!--
+ # rdoc-file=process.c
+ # - system([env, ] command_line, options = {}, exception: false) -> true, false, or nil
+ # - system([env, ] exe_path, *args, options = {}, exception: false) -> true, false, or nil
+ # -->
+ # Creates a new child process by doing one of the following in that process:
#
- # The `:chdir` key in `options` specifies the current directory.
+ # * Passing string `command_line` to the shell.
+ # * Invoking the executable at `exe_path`.
#
- # pid = spawn(command, :chdir=>"/var/tmp")
#
- # spawn closes all non-standard unspecified descriptors by default. The
- # "standard" descriptors are 0, 1 and 2. This behavior is specified by
- # :close_others option. :close_others doesn't affect the standard descriptors
- # which are closed only if :close is specified explicitly.
+ # This method has potential security vulnerabilities if called with untrusted
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
#
- # pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
- # pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
+ # Returns:
#
- # :close_others is false by default for spawn and IO.popen.
+ # * `true` if the command exits with status zero.
+ # * `false` if the exit status is a non-zero integer.
+ # * `nil` if the command could not execute.
#
- # Note that fds which close-on-exec flag is already set are closed regardless of
- # :close_others option.
#
- # So IO.pipe and spawn can be used as IO.popen.
+ # Raises an exception (instead of returning `false` or `nil`) if keyword
+ # argument `exception` is set to `true`.
#
- # # similar to r = IO.popen(command)
- # r, w = IO.pipe
- # pid = spawn(command, :out=>w) # r, w is closed in the child process.
- # w.close
+ # Assigns the command's error status to `$?`.
#
- # :close is specified as a hash value to close a fd individually.
+ # The new process is created using the [system system
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/s
+ # ystem.html); it may inherit some of its environment from the calling program
+ # (possibly including open file descriptors).
#
- # f = open(foo)
- # system(command, f=>:close) # don't inherit f.
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
#
- # If a file descriptor need to be inherited, io=>io can be used.
+ # Argument `options` is a hash of options for the new process; see [Execution
+ # Options](rdoc-ref:Process@Execution+Options).
#
- # # valgrind has --log-fd option for log destination.
- # # log_w=>log_w indicates log_w.fileno inherits to child process.
- # log_r, log_w = IO.pipe
- # pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
- # log_w.close
- # p log_r.read
+ # The first required argument is one of the following:
#
- # It is also possible to exchange file descriptors.
+ # * `command_line` if it is a string, and if it begins with a shell reserved
+ # word or special built-in, or if it contains one or more meta characters.
+ # * `exe_path` otherwise.
#
- # pid = spawn(command, :out=>:err, :err=>:out)
#
- # The hash keys specify file descriptors in the child process. The hash values
- # specifies file descriptors in the parent process. So the above specifies
- # exchanging stdout and stderr. Internally, `spawn` uses an extra file
- # descriptor to resolve such cyclic file descriptor mapping.
+ # **Argument `command_line`**
#
- # See Kernel.exec for the standard shell.
+ # String argument `command_line` is a command line to be passed to a shell; it
+ # must begin with a shell reserved word, begin with a special built-in, or
+ # contain meta characters:
#
- def self?.spawn: (String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> Integer
- | (Hash[string, string?] env, String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> Integer
-
- # <!--
- # rdoc-file=process.c
- # - system([env,] command... [,options], exception: false) -> true, false or nil
- # -->
- # Executes *command...* in a subshell. *command...* is one of following forms.
+ # system('if true; then echo "Foo"; fi') # => true # Shell reserved word.
+ # system('echo') # => true # Built-in.
+ # system('date > /tmp/date.tmp') # => true # Contains meta character.
+ # system('date > /nop/date.tmp') # => false
+ # system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
#
- # This method has potential security vulnerabilities if called with untrusted
- # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
+ # Assigns the command's error status to `$?`:
#
- # `commandline`
- # : command line string which is passed to the standard shell
- # `cmdname, arg1, ...`
- # : command name and one or more arguments (no shell)
- # `[cmdname, argv0], arg1, ...`
- # : command name, `argv[0]` and zero or more arguments (no shell)
+ # system('echo') # => true # Built-in.
+ # $? # => #<Process::Status: pid 640610 exit 0>
+ # system('date > /nop/date.tmp') # => false
+ # $? # => #<Process::Status: pid 640742 exit 2>
#
+ # The command line may also contain arguments and options for the command:
#
- # system returns `true` if the command gives zero exit status, `false` for non
- # zero exit status. Returns `nil` if command execution fails. An error status is
- # available in `$?`.
+ # system('echo "Foo"') # => true
#
- # If the `exception: true` argument is passed, the method raises an exception
- # instead of returning `false` or `nil`.
+ # Output:
#
- # The arguments are processed in the same way as for Kernel#spawn.
+ # Foo
#
- # The hash arguments, env and options, are same as #exec and #spawn. See
- # Kernel#spawn for details.
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
+ # shell.
#
- # system("echo *")
- # system("echo", "*")
+ # Raises an exception if the new process could not execute.
#
- # *produces:*
+ # **Argument `exe_path`**
#
- # config.h main.rb
- # *
+ # Argument `exe_path` is one of the following:
#
- # Error handling:
+ # * The string path to an executable to be called.
+ # * A 2-element array containing the path to an executable and the string to
+ # be used as the name of the executing process.
#
- # system("cat nonexistent.txt")
- # # => false
- # system("catt nonexistent.txt")
- # # => nil
#
- # system("cat nonexistent.txt", exception: true)
- # # RuntimeError (Command failed with exit 1: cat)
- # system("catt nonexistent.txt", exception: true)
- # # Errno::ENOENT (No such file or directory - catt)
+ # Example:
#
- # See Kernel#exec for the standard shell.
+ # system('/usr/bin/date') # => true # Path to date on Unix-style system.
+ # system('foo') # => nil # Command failed.
#
+ # Output:
+ #
+ # Mon Aug 28 11:43:10 AM CDT 2023
+ #
+ # Assigns the command's error status to `$?`:
+ #
+ # system('/usr/bin/date') # => true
+ # $? # => #<Process::Status: pid 645605 exit 0>
+ # system('foo') # => nil
+ # $? # => #<Process::Status: pid 645608 exit 127>
+ #
+ # Ruby invokes the executable directly, with no shell and no shell expansion:
+ #
+ # system('doesnt_exist') # => nil
+ #
+ # If one or more `args` is given, each is an argument or option to be passed to
+ # the executable:
+ #
+ # system('echo', 'C*') # => true
+ # system('echo', 'hello', 'world') # => true
+ #
+ # Output:
+ #
+ # C*
+ # hello world
+ #
+ # Raises an exception if the new process could not execute.
+ #
def self?.system: (String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> (NilClass | FalseClass | TrueClass)
| (Hash[string, string?] env, String command, *String args, ?unsetenv_others: boolish, ?pgroup: true | Integer, ?umask: Integer, ?in: redirect_fd, ?out: redirect_fd, ?err: redirect_fd, ?close_others: boolish, ?chdir: String) -> (NilClass | FalseClass | TrueClass)
# <!--
# rdoc-file=object.c
@@ -2953,18 +2915,9 @@
# - obj.yield_self {|x| block } -> an_object
# -->
# Yields self to the block and returns the result of the block.
#
# "my string".yield_self {|s| s.upcase } #=> "MY STRING"
- #
- # Good usage for `then` is value piping in method chains:
- #
- # require 'open-uri'
- # require 'json'
- #
- # construct_url(arguments).
- # then {|url| URI(url).read }.
- # then {|response| JSON.parse(response) }
#
def yield_self: [X] () { (self) -> X } -> X
| () -> Enumerator[self, untyped]
%a{annotate:rdoc:skip}