rbs 3.3.2 → 3.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/comments.yml +2 -5
  3. data/.github/workflows/ruby.yml +7 -8
  4. data/.github/workflows/typecheck.yml +37 -0
  5. data/CHANGELOG.md +65 -0
  6. data/Gemfile +1 -1
  7. data/Gemfile.lock +11 -11
  8. data/README.md +1 -0
  9. data/Rakefile +2 -2
  10. data/Steepfile +2 -2
  11. data/core/array.rbs +19 -49
  12. data/core/basic_object.rbs +2 -2
  13. data/core/comparable.rbs +17 -8
  14. data/core/complex.rbs +82 -43
  15. data/core/data.rbs +2 -4
  16. data/core/dir.rbs +635 -295
  17. data/core/enumerable.rbs +11 -18
  18. data/core/enumerator.rbs +37 -31
  19. data/core/errors.rbs +4 -0
  20. data/core/false_class.rbs +34 -15
  21. data/core/fiber.rbs +23 -0
  22. data/core/file.rbs +329 -120
  23. data/core/float.rbs +17 -32
  24. data/core/gc.rbs +17 -11
  25. data/core/hash.rbs +22 -44
  26. data/core/integer.rbs +82 -113
  27. data/core/io/buffer.rbs +90 -47
  28. data/core/io.rbs +54 -121
  29. data/core/kernel.rbs +442 -489
  30. data/core/match_data.rbs +55 -56
  31. data/core/module.rbs +45 -1
  32. data/core/nil_class.rbs +98 -35
  33. data/core/numeric.rbs +22 -32
  34. data/core/object_space/weak_key_map.rbs +102 -0
  35. data/core/process.rbs +1242 -655
  36. data/core/ractor.rbs +139 -120
  37. data/core/range.rbs +100 -4
  38. data/core/rational.rbs +0 -4
  39. data/core/rbs/unnamed/argf.rbs +16 -8
  40. data/core/rbs/unnamed/env_class.rbs +0 -24
  41. data/core/refinement.rbs +8 -0
  42. data/core/regexp.rbs +1149 -598
  43. data/core/ruby_vm.rbs +126 -12
  44. data/core/rubygems/platform.rbs +9 -0
  45. data/core/rubygems/rubygems.rbs +1 -1
  46. data/core/rubygems/version.rbs +5 -1
  47. data/core/set.rbs +20 -22
  48. data/core/signal.rbs +4 -4
  49. data/core/string.rbs +283 -230
  50. data/core/string_io.rbs +2 -14
  51. data/core/struct.rbs +404 -24
  52. data/core/symbol.rbs +1 -19
  53. data/core/thread.rbs +29 -12
  54. data/core/time.rbs +227 -104
  55. data/core/trace_point.rbs +2 -5
  56. data/core/true_class.rbs +54 -21
  57. data/core/warning.rbs +14 -11
  58. data/docs/data_and_struct.md +29 -0
  59. data/docs/gem.md +58 -0
  60. data/docs/syntax.md +3 -5
  61. data/docs/tools.md +1 -0
  62. data/ext/rbs_extension/lexer.c +643 -559
  63. data/ext/rbs_extension/lexer.re +5 -1
  64. data/ext/rbs_extension/parser.c +12 -3
  65. data/ext/rbs_extension/unescape.c +7 -47
  66. data/lib/rbs/cli/diff.rb +4 -1
  67. data/lib/rbs/cli/validate.rb +280 -0
  68. data/lib/rbs/cli.rb +2 -194
  69. data/lib/rbs/collection/config.rb +5 -6
  70. data/lib/rbs/collection/sources/git.rb +1 -1
  71. data/lib/rbs/collection.rb +1 -0
  72. data/lib/rbs/diff.rb +7 -4
  73. data/lib/rbs/errors.rb +11 -0
  74. data/lib/rbs/test/errors.rb +10 -2
  75. data/lib/rbs/test/guaranteed.rb +2 -3
  76. data/lib/rbs/test/type_check.rb +15 -10
  77. data/lib/rbs/test.rb +3 -3
  78. data/lib/rbs/types.rb +29 -0
  79. data/lib/rbs/unit_test/convertibles.rb +176 -0
  80. data/lib/rbs/unit_test/spy.rb +136 -0
  81. data/lib/rbs/unit_test/type_assertions.rb +341 -0
  82. data/lib/rbs/unit_test/with_aliases.rb +143 -0
  83. data/lib/rbs/unit_test.rb +6 -0
  84. data/lib/rbs/version.rb +1 -1
  85. data/sig/cli/validate.rbs +43 -0
  86. data/sig/diff.rbs +3 -1
  87. data/sig/errors.rbs +8 -0
  88. data/sig/rbs.rbs +1 -1
  89. data/sig/test/errors.rbs +52 -0
  90. data/sig/test/guranteed.rbs +9 -0
  91. data/sig/test/type_check.rbs +19 -0
  92. data/sig/test.rbs +82 -0
  93. data/sig/types.rbs +6 -1
  94. data/sig/unit_test/convertibles.rbs +154 -0
  95. data/sig/unit_test/spy.rbs +28 -0
  96. data/sig/unit_test/type_assertions.rbs +194 -0
  97. data/sig/unit_test/with_aliases.rbs +136 -0
  98. data/stdlib/base64/0/base64.rbs +307 -45
  99. data/stdlib/bigdecimal/0/big_decimal.rbs +35 -15
  100. data/stdlib/coverage/0/coverage.rbs +2 -2
  101. data/stdlib/csv/0/csv.rbs +25 -55
  102. data/stdlib/date/0/date.rbs +1 -43
  103. data/stdlib/date/0/date_time.rbs +1 -13
  104. data/stdlib/delegate/0/delegator.rbs +186 -0
  105. data/stdlib/delegate/0/kernel.rbs +47 -0
  106. data/stdlib/delegate/0/simple_delegator.rbs +98 -0
  107. data/stdlib/did_you_mean/0/did_you_mean.rbs +1 -1
  108. data/stdlib/erb/0/erb.rbs +2 -2
  109. data/stdlib/fileutils/0/fileutils.rbs +0 -19
  110. data/stdlib/io-console/0/io-console.rbs +12 -1
  111. data/stdlib/ipaddr/0/ipaddr.rbs +2 -1
  112. data/stdlib/json/0/json.rbs +320 -81
  113. data/stdlib/logger/0/logger.rbs +9 -5
  114. data/stdlib/minitest/0/minitest/test/lifecycle_hooks.rbs +6 -6
  115. data/stdlib/monitor/0/monitor.rbs +78 -0
  116. data/stdlib/net-http/0/net-http.rbs +1880 -543
  117. data/stdlib/objspace/0/objspace.rbs +19 -13
  118. data/stdlib/openssl/0/openssl.rbs +508 -127
  119. data/stdlib/optparse/0/optparse.rbs +25 -11
  120. data/stdlib/pathname/0/pathname.rbs +1 -1
  121. data/stdlib/pp/0/pp.rbs +2 -5
  122. data/stdlib/prettyprint/0/prettyprint.rbs +2 -2
  123. data/stdlib/pstore/0/pstore.rbs +2 -4
  124. data/stdlib/rdoc/0/comment.rbs +1 -2
  125. data/stdlib/resolv/0/resolv.rbs +4 -2
  126. data/stdlib/socket/0/socket.rbs +2 -2
  127. data/stdlib/socket/0/unix_socket.rbs +2 -2
  128. data/stdlib/strscan/0/string_scanner.rbs +3 -2
  129. data/stdlib/tempfile/0/tempfile.rbs +1 -1
  130. data/stdlib/uri/0/common.rbs +245 -123
  131. metadata +24 -4
  132. data/lib/rbs/test/spy.rb +0 -6
data/core/kernel.rbs CHANGED
@@ -362,25 +362,63 @@ module Kernel : BasicObject
362
362
 
363
363
  # <!--
364
364
  # rdoc-file=process.c
365
- # - Kernel.fork [{ block }] -> integer or nil
366
- # - Process.fork [{ block }] -> integer or nil
365
+ # - Process.fork { ... } -> integer or nil
366
+ # - Process.fork -> integer or nil
367
367
  # -->
368
- # Creates a subprocess. If a block is specified, that block is run in the
369
- # subprocess, and the subprocess terminates with a status of zero. Otherwise,
370
- # the `fork` call returns twice, once in the parent, returning the process ID of
371
- # the child, and once in the child, returning *nil*. The child process can exit
372
- # using Kernel.exit! to avoid running any `at_exit` functions. The parent
373
- # process should use Process.wait to collect the termination statuses of its
374
- # children or use Process.detach to register disinterest in their status;
375
- # otherwise, the operating system may accumulate zombie processes.
368
+ # Creates a child process.
376
369
  #
377
- # The thread calling fork is the only thread in the created child process. fork
378
- # doesn't copy other threads.
370
+ # With a block given, runs the block in the child process; on block exit, the
371
+ # child terminates with a status of zero:
379
372
  #
380
- # If fork is not usable, Process.respond_to?(:fork) returns false.
373
+ # puts "Before the fork: #{Process.pid}"
374
+ # fork do
375
+ # puts "In the child process: #{Process.pid}"
376
+ # end # => 382141
377
+ # puts "After the fork: #{Process.pid}"
381
378
  #
382
- # Note that fork(2) is not available on some platforms like Windows and NetBSD
383
- # 4. Therefore you should use spawn() instead of fork().
379
+ # Output:
380
+ #
381
+ # Before the fork: 420496
382
+ # After the fork: 420496
383
+ # In the child process: 420520
384
+ #
385
+ # With no block given, the `fork` call returns twice:
386
+ #
387
+ # * Once in the parent process, returning the pid of the child process.
388
+ # * Once in the child process, returning `nil`.
389
+ #
390
+ #
391
+ # Example:
392
+ #
393
+ # puts "This is the first line before the fork (pid #{Process.pid})"
394
+ # puts fork
395
+ # puts "This is the second line after the fork (pid #{Process.pid})"
396
+ #
397
+ # Output:
398
+ #
399
+ # This is the first line before the fork (pid 420199)
400
+ # 420223
401
+ # This is the second line after the fork (pid 420199)
402
+ #
403
+ # This is the second line after the fork (pid 420223)
404
+ #
405
+ # In either case, the child process may exit using Kernel.exit! to avoid the
406
+ # call to Kernel#at_exit.
407
+ #
408
+ # To avoid zombie processes, the parent process should call either:
409
+ #
410
+ # * Process.wait, to collect the termination statuses of its children.
411
+ # * Process.detach, to register disinterest in their status.
412
+ #
413
+ #
414
+ # The thread calling `fork` is the only thread in the created child process;
415
+ # `fork` doesn't copy other threads.
416
+ #
417
+ # Note that method `fork` is available on some platforms, but not on others:
418
+ #
419
+ # Process.respond_to?(:fork) # => true # Would be false on some.
420
+ #
421
+ # If not, you may use ::spawn instead of `fork`.
384
422
  #
385
423
  def self?.fork: () -> Integer?
386
424
  | () { () -> void } -> Integer
@@ -407,39 +445,53 @@ module Kernel : BasicObject
407
445
 
408
446
  # <!--
409
447
  # rdoc-file=complex.c
410
- # - Complex(x[, y], exception: true) -> numeric or nil
448
+ # - Complex(abs, arg = 0, exception: true) -> complex or nil
449
+ # - Complex(s, exception: true) -> complex or nil
411
450
  # -->
412
- # Returns x+i*y;
451
+ # Returns a new Complex object if the arguments are valid; otherwise raises an
452
+ # exception if `exception` is `true`; otherwise returns `nil`.
413
453
  #
414
- # Complex(1, 2) #=> (1+2i)
415
- # Complex('1+2i') #=> (1+2i)
416
- # Complex(nil) #=> TypeError
417
- # Complex(1, nil) #=> TypeError
454
+ # With Numeric argument `abs`, returns `Complex.rect(abs, arg)` if the arguments
455
+ # are valid.
418
456
  #
419
- # Complex(1, nil, exception: false) #=> nil
420
- # Complex('1+2', exception: false) #=> nil
457
+ # With string argument `s`, returns a new Complex object if the argument is
458
+ # valid; the string may have:
421
459
  #
422
- # Syntax of string form:
460
+ # * One or two numeric substrings, each of which specifies a Complex, Float,
461
+ # Integer, Numeric, or Rational value, specifying [rectangular
462
+ # coordinates](rdoc-ref:Complex@Rectangular+Coordinates):
423
463
  #
424
- # string form = extra spaces , complex , extra spaces ;
425
- # complex = real part | [ sign ] , imaginary part
426
- # | real part , sign , imaginary part
427
- # | rational , "@" , rational ;
428
- # real part = rational ;
429
- # imaginary part = imaginary unit | unsigned rational , imaginary unit ;
430
- # rational = [ sign ] , unsigned rational ;
431
- # unsigned rational = numerator | numerator , "/" , denominator ;
432
- # numerator = integer part | fractional part | integer part , fractional part ;
433
- # denominator = digits ;
434
- # integer part = digits ;
435
- # fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ;
436
- # imaginary unit = "i" | "I" | "j" | "J" ;
437
- # sign = "-" | "+" ;
438
- # digits = digit , { digit | "_" , digit };
439
- # digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ;
440
- # extra spaces = ? \s* ? ;
464
+ # * Sign-separated real and imaginary numeric substrings (with trailing
465
+ # character `'i'`):
466
+ #
467
+ # Complex('1+2i') # => (1+2i)
468
+ # Complex('+1+2i') # => (1+2i)
469
+ # Complex('+1-2i') # => (1-2i)
470
+ # Complex('-1+2i') # => (-1+2i)
471
+ # Complex('-1-2i') # => (-1-2i)
472
+ #
473
+ # * Real-only numeric string (without trailing character `'i'`):
474
+ #
475
+ # Complex('1') # => (1+0i)
476
+ # Complex('+1') # => (1+0i)
477
+ # Complex('-1') # => (-1+0i)
478
+ #
479
+ # * Imaginary-only numeric string (with trailing character `'i'`):
441
480
  #
442
- # See String#to_c.
481
+ # Complex('1i') # => (0+1i)
482
+ # Complex('+1i') # => (0+1i)
483
+ # Complex('-1i') # => (0-1i)
484
+ #
485
+ #
486
+ # * At-sign separated real and imaginary rational substrings, each of which
487
+ # specifies a Rational value, specifying [polar
488
+ # coordinates](rdoc-ref:Complex@Polar+Coordinates):
489
+ #
490
+ # Complex('1/2@3/4') # => (0.36584443443691045+0.34081938001166706i)
491
+ # Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i)
492
+ # Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i)
493
+ # Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i)
494
+ # Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i)
443
495
  #
444
496
  def self?.Complex: (_ToC complex_like, ?exception: true) -> Complex
445
497
  | (_ToC complex_like, exception: bool) -> Complex?
@@ -493,7 +545,7 @@ module Kernel : BasicObject
493
545
  | [K, V] (hash[K, V] hash_like) -> Hash[K, V]
494
546
 
495
547
  # <!--
496
- # rdoc-file=object.c
548
+ # rdoc-file=kernel.rb
497
549
  # - Integer(object, base = 0, exception: true) -> integer or nil
498
550
  # -->
499
551
  # Returns an integer converted from `object`.
@@ -511,7 +563,7 @@ module Kernel : BasicObject
511
563
  # Integer(-1) # => -1
512
564
  #
513
565
  # With floating-point argument `object` given, returns `object` truncated to an
514
- # intger:
566
+ # integer:
515
567
  #
516
568
  # Integer(1.9) # => 1 # Rounds toward zero.
517
569
  # Integer(-1.9) # => -1 # Rounds toward zero.
@@ -700,11 +752,13 @@ module Kernel : BasicObject
700
752
  # <!--
701
753
  # rdoc-file=process.c
702
754
  # - abort
703
- # - Kernel::abort([msg])
704
- # - Process.abort([msg])
755
+ # - Process.abort(msg = nil)
705
756
  # -->
706
- # Terminate execution immediately, effectively by calling `Kernel.exit(false)`.
707
- # If *msg* is given, it is written to STDERR prior to terminating.
757
+ # Terminates execution immediately, effectively by calling `Kernel.exit(false)`.
758
+ #
759
+ # If string argument `msg` is given, it is written to STDERR prior to
760
+ # termination; otherwise, if an exception was raised, prints its message and
761
+ # backtrace.
708
762
  #
709
763
  def self?.abort: (?string msg) -> bot
710
764
 
@@ -759,68 +813,102 @@ module Kernel : BasicObject
759
813
  # rdoc-file=proc.c
760
814
  # - binding -> a_binding
761
815
  # -->
762
- # Returns a `Binding` object, describing the variable and method bindings at the
763
- # point of call. This object can be used when calling `eval` to execute the
764
- # evaluated command in this environment. See also the description of class
765
- # `Binding`.
816
+ # Returns a Binding object, describing the variable and method bindings at the
817
+ # point of call. This object can be used when calling Binding#eval to execute
818
+ # the evaluated command in this environment, or extracting its local variables.
819
+ #
820
+ # class User
821
+ # def initialize(name, position)
822
+ # @name = name
823
+ # @position = position
824
+ # end
825
+ #
826
+ # def get_binding
827
+ # binding
828
+ # end
829
+ # end
766
830
  #
767
- # def get_binding(param)
768
- # binding
831
+ # user = User.new('Joan', 'manager')
832
+ # template = '{name: @name, position: @position}'
833
+ #
834
+ # # evaluate template in context of the object
835
+ # eval(template, user.get_binding)
836
+ # #=> {:name=>"Joan", :position=>"manager"}
837
+ #
838
+ # Binding#local_variable_get can be used to access the variables whose names are
839
+ # reserved Ruby keywords:
840
+ #
841
+ # # This is valid parameter declaration, but `if` parameter can't
842
+ # # be accessed by name, because it is a reserved word.
843
+ # def validate(field, validation, if: nil)
844
+ # condition = binding.local_variable_get('if')
845
+ # return unless condition
846
+ #
847
+ # # ...Some implementation ...
769
848
  # end
770
- # b = get_binding("hello")
771
- # eval("param", b) #=> "hello"
849
+ #
850
+ # validate(:name, :empty?, if: false) # skips validation
851
+ # validate(:name, :empty?, if: true) # performs validation
772
852
  #
773
853
  def self?.binding: () -> Binding
774
854
 
775
855
  # <!--
776
856
  # rdoc-file=process.c
777
- # - exit(status=true)
778
- # - Kernel::exit(status=true)
779
- # - Process::exit(status=true)
857
+ # - exit(status = true)
858
+ # - Process.exit(status = true)
780
859
  # -->
781
- # Initiates the termination of the Ruby script by raising the SystemExit
782
- # exception. This exception may be caught. The optional parameter is used to
783
- # return a status code to the invoking environment. `true` and `FALSE` of
784
- # *status* means success and failure respectively. The interpretation of other
785
- # integer values are system dependent.
860
+ # Initiates termination of the Ruby script by raising SystemExit; the exception
861
+ # may be caught. Returns exit status `status` to the underlying operating
862
+ # system.
863
+ #
864
+ # Values `true` and `false` for argument `status` indicate, respectively,
865
+ # success and failure; The meanings of integer values are system-dependent.
866
+ #
867
+ # Example:
786
868
  #
787
869
  # begin
788
870
  # exit
789
- # puts "never get here"
871
+ # puts 'Never get here.'
790
872
  # rescue SystemExit
791
- # puts "rescued a SystemExit exception"
873
+ # puts 'Rescued a SystemExit exception.'
792
874
  # end
793
- # puts "after begin block"
875
+ # puts 'After begin block.'
794
876
  #
795
- # *produces:*
877
+ # Output:
796
878
  #
797
- # rescued a SystemExit exception
798
- # after begin block
879
+ # Rescued a SystemExit exception.
880
+ # After begin block.
799
881
  #
800
- # Just prior to termination, Ruby executes any `at_exit` functions (see
801
- # Kernel::at_exit) and runs any object finalizers (see
882
+ # Just prior to final termination, Ruby executes any at-exit procedures (see
883
+ # Kernel::at_exit) and any object finalizers (see
802
884
  # ObjectSpace::define_finalizer).
803
885
  #
804
- # at_exit { puts "at_exit function" }
805
- # ObjectSpace.define_finalizer("string", proc { puts "in finalizer" })
886
+ # Example:
887
+ #
888
+ # at_exit { puts 'In at_exit function.' }
889
+ # ObjectSpace.define_finalizer('string', proc { puts 'In finalizer.' })
806
890
  # exit
807
891
  #
808
- # *produces:*
892
+ # Output:
809
893
  #
810
- # at_exit function
811
- # in finalizer
894
+ # In at_exit function.
895
+ # In finalizer.
812
896
  #
813
897
  def self?.exit: (?int | bool status) -> bot
814
898
 
815
899
  # <!--
816
900
  # rdoc-file=process.c
817
- # - Process.exit!(status=false)
901
+ # - exit!(status = false)
902
+ # - Process.exit!(status = false)
818
903
  # -->
819
- # Exits the process immediately. No exit handlers are run. *status* is returned
820
- # to the underlying system as the exit status.
904
+ # Exits the process immediately; no exit handlers are called. Returns exit
905
+ # status `status` to the underlying operating system.
821
906
  #
822
907
  # Process.exit!(true)
823
908
  #
909
+ # Values `true` and `false` for argument `status` indicate, respectively,
910
+ # success and failure; The meanings of integer values are system-dependent.
911
+ #
824
912
  def self?.exit!: (?int | bool status) -> bot
825
913
 
826
914
  # <!-- rdoc-file=eval.c -->
@@ -882,8 +970,6 @@ module Kernel : BasicObject
882
970
  # For details on `format_string`, see [Format
883
971
  # Specifications](rdoc-ref:format_specifications.rdoc).
884
972
  #
885
- # Kernel#format is an alias for Kernel#sprintf.
886
- #
887
973
  def self?.format: (String format, *untyped args) -> String
888
974
 
889
975
  # <!--
@@ -895,8 +981,6 @@ module Kernel : BasicObject
895
981
  # For details on `format_string`, see [Format
896
982
  # Specifications](rdoc-ref:format_specifications.rdoc).
897
983
  #
898
- # Kernel#format is an alias for Kernel#sprintf.
899
- #
900
984
  alias sprintf format
901
985
 
902
986
  alias self.sprintf self.format
@@ -947,7 +1031,7 @@ module Kernel : BasicObject
947
1031
 
948
1032
  # <!--
949
1033
  # rdoc-file=load.c
950
- # - load(file, wrap = false)
1034
+ # - load(filename, wrap=false) -> true
951
1035
  # -->
952
1036
  # Loads and executes the Ruby program in the file *filename*.
953
1037
  #
@@ -975,7 +1059,7 @@ module Kernel : BasicObject
975
1059
  def self?.load: (String filename, ?Module | bool) -> bool
976
1060
 
977
1061
  # <!--
978
- # rdoc-file=vm_eval.c
1062
+ # rdoc-file=kernel.rb
979
1063
  # - loop { block }
980
1064
  # - loop -> an_enumerator
981
1065
  # -->
@@ -1011,21 +1095,10 @@ module Kernel : BasicObject
1011
1095
  # - open(path, mode = 'r', perm = 0666, **opts) -> io or nil
1012
1096
  # - open(path, mode = 'r', perm = 0666, **opts) {|io| ... } -> obj
1013
1097
  # -->
1014
- # Creates an IO object connected to the given stream, file, or subprocess.
1015
- #
1016
- # Required string argument `path` determines which of the following occurs:
1017
- #
1018
- # * The file at the specified `path` is opened.
1019
- # * The process forks.
1020
- # * A subprocess is created.
1021
- #
1098
+ # Creates an IO object connected to the given file.
1022
1099
  #
1023
- # Each of these is detailed below.
1024
- #
1025
- # **File Opened**
1026
- #
1027
- # If `path` does *not* start with a pipe character (`'|'`), a file stream is
1028
- # opened with `File.open(path, mode, perm, **opts)`.
1100
+ # This method has potential security vulnerabilities if called with untrusted
1101
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
1029
1102
  #
1030
1103
  # With no block given, file stream is returned:
1031
1104
  #
@@ -1042,66 +1115,6 @@ module Kernel : BasicObject
1042
1115
  #
1043
1116
  # See File.open for details.
1044
1117
  #
1045
- # **Process Forked**
1046
- #
1047
- # If `path` is the 2-character string `'|-'`, the process forks and the child
1048
- # process is connected to the parent.
1049
- #
1050
- # With no block given:
1051
- #
1052
- # io = open('|-')
1053
- # if io
1054
- # $stderr.puts "In parent, child pid is #{io.pid}."
1055
- # else
1056
- # $stderr.puts "In child, pid is #{$$}."
1057
- # end
1058
- #
1059
- # Output:
1060
- #
1061
- # In parent, child pid is 27903.
1062
- # In child, pid is 27903.
1063
- #
1064
- # With a block given:
1065
- #
1066
- # open('|-') do |io|
1067
- # if io
1068
- # $stderr.puts "In parent, child pid is #{io.pid}."
1069
- # else
1070
- # $stderr.puts "In child, pid is #{$$}."
1071
- # end
1072
- # end
1073
- #
1074
- # Output:
1075
- #
1076
- # In parent, child pid is 28427.
1077
- # In child, pid is 28427.
1078
- #
1079
- # **Subprocess Created**
1080
- #
1081
- # If `path` is `'|command'` (`'command' != '-'`), a new subprocess runs the
1082
- # command; its open stream is returned. Note that the command may be processed
1083
- # by shell if it contains shell metacharacters.
1084
- #
1085
- # With no block given:
1086
- #
1087
- # io = open('|echo "Hi!"') # => #<IO:fd 12>
1088
- # print io.gets
1089
- # io.close
1090
- #
1091
- # Output:
1092
- #
1093
- # "Hi!"
1094
- #
1095
- # With a block given, calls the block with the stream, then closes the stream:
1096
- #
1097
- # open('|echo "Hi!"') do |io|
1098
- # print io.gets
1099
- # end
1100
- #
1101
- # Output:
1102
- #
1103
- # "Hi!"
1104
- #
1105
1118
  def self?.open: (String name, ?String mode, ?Integer perm) -> IO?
1106
1119
  | [T] (String name, ?String mode, ?Integer perm) { (IO) -> T } -> T
1107
1120
 
@@ -1255,6 +1268,10 @@ module Kernel : BasicObject
1255
1268
  # 0..4
1256
1269
  # [0..4, 0..4, 0..4]
1257
1270
  #
1271
+ # Kernel#p is designed for debugging purposes. Ruby implementations may define
1272
+ # Kernel#p to be uninterruptible in whole or in part. On CRuby, Kernel#p's
1273
+ # writing of data is uninterruptible.
1274
+ #
1258
1275
  def self?.p: [T < _Inspect] (T arg0) -> T
1259
1276
  | (_Inspect arg0, _Inspect arg1, *_Inspect rest) -> Array[_Inspect]
1260
1277
  | () -> nil
@@ -1399,7 +1416,7 @@ module Kernel : BasicObject
1399
1416
 
1400
1417
  # <!--
1401
1418
  # rdoc-file=load.c
1402
- # - require_relative(file)
1419
+ # - require_relative(string) -> true or false
1403
1420
  # -->
1404
1421
  # Ruby tries to load the library named *string* relative to the directory
1405
1422
  # containing the requiring file. If the file does not exist a LoadError is
@@ -1551,19 +1568,17 @@ module Kernel : BasicObject
1551
1568
 
1552
1569
  # <!--
1553
1570
  # rdoc-file=process.c
1554
- # - sleep([duration]) -> integer
1571
+ # - sleep(secs = nil) -> slept_secs
1555
1572
  # -->
1556
- # Suspends the current thread for *duration* seconds (which may be any number,
1557
- # including a `Float` with fractional seconds). Returns the actual number of
1558
- # seconds slept (rounded), which may be less than that asked for if another
1559
- # thread calls Thread#run. Called without an argument, sleep() will sleep
1560
- # forever.
1573
+ # Suspends execution of the current thread for the number of seconds specified
1574
+ # by numeric argument `secs`, or forever if `secs` is `nil`; returns the integer
1575
+ # number of seconds suspended (rounded).
1561
1576
  #
1562
- # Time.new #=> 2008-03-08 19:56:19 +0900
1563
- # sleep 1.2 #=> 1
1564
- # Time.new #=> 2008-03-08 19:56:20 +0900
1565
- # sleep 1.9 #=> 2
1566
- # Time.new #=> 2008-03-08 19:56:22 +0900
1577
+ # Time.new # => 2008-03-08 19:56:19 +0900
1578
+ # sleep 1.2 # => 1
1579
+ # Time.new # => 2008-03-08 19:56:20 +0900
1580
+ # sleep 1.9 # => 2
1581
+ # Time.new # => 2008-03-08 19:56:22 +0900
1567
1582
  #
1568
1583
  def self?.sleep: (?nil) -> bot
1569
1584
  | (Integer | Float | _Divmod duration) -> Integer
@@ -1676,31 +1691,31 @@ module Kernel : BasicObject
1676
1691
  # newline character to the string if the string does not end in a newline, and
1677
1692
  # calls Warning.warn with the string.
1678
1693
  #
1679
- # warn("warning 1", "warning 2")
1694
+ # warn("warning 1", "warning 2")
1680
1695
  #
1681
- # <em>produces:</em>
1696
+ # *produces:*
1682
1697
  #
1683
- # warning 1
1684
- # warning 2
1698
+ # warning 1
1699
+ # warning 2
1685
1700
  #
1686
1701
  # If the `uplevel` keyword argument is given, the string will be prepended with
1687
1702
  # information for the given caller frame in the same format used by the
1688
1703
  # `rb_warn` C function.
1689
1704
  #
1690
- # # In baz.rb
1691
- # def foo
1692
- # warn("invalid call to foo", uplevel: 1)
1693
- # end
1705
+ # # In baz.rb
1706
+ # def foo
1707
+ # warn("invalid call to foo", uplevel: 1)
1708
+ # end
1694
1709
  #
1695
- # def bar
1696
- # foo
1697
- # end
1710
+ # def bar
1711
+ # foo
1712
+ # end
1698
1713
  #
1699
- # bar
1714
+ # bar
1700
1715
  #
1701
- # <em>produces:</em>
1716
+ # *produces:*
1702
1717
  #
1703
- # baz.rb:6: warning: invalid call to foo
1718
+ # baz.rb:6: warning: invalid call to foo
1704
1719
  #
1705
1720
  # If `category` keyword argument is given, passes the category to
1706
1721
  # `Warning.warn`. The category given must be be one of the following
@@ -1716,76 +1731,92 @@ module Kernel : BasicObject
1716
1731
 
1717
1732
  # <!--
1718
1733
  # rdoc-file=process.c
1719
- # - exec([env,] command... [,options])
1734
+ # - exec([env, ] command_line, options = {})
1735
+ # - exec([env, ] exe_path, *args, options = {})
1720
1736
  # -->
1721
- # Replaces the current process by running the given external *command*, which
1722
- # can take one of the following forms:
1737
+ # Replaces the current process by doing one of the following:
1738
+ #
1739
+ # * Passing string `command_line` to the shell.
1740
+ # * Invoking the executable at `exe_path`.
1741
+ #
1742
+ #
1743
+ # This method has potential security vulnerabilities if called with untrusted
1744
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
1745
+ #
1746
+ # The new process is created using the [exec system
1747
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/e
1748
+ # xecve.html); it may inherit some of its environment from the calling program
1749
+ # (possibly including open file descriptors).
1750
+ #
1751
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
1752
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
1753
+ #
1754
+ # Argument `options` is a hash of options for the new process; see [Execution
1755
+ # Options](rdoc-ref:Process@Execution+Options).
1756
+ #
1757
+ # The first required argument is one of the following:
1758
+ #
1759
+ # * `command_line` if it is a string, and if it begins with a shell reserved
1760
+ # word or special built-in, or if it contains one or more meta characters.
1761
+ # * `exe_path` otherwise.
1723
1762
  #
1724
- # `exec(commandline)`
1725
- # : command line string which is passed to the standard shell
1726
- # `exec(cmdname, arg1, ...)`
1727
- # : command name and one or more arguments (no shell)
1728
- # `exec([cmdname, argv0], arg1, ...)`
1729
- # : command name, `argv[0]` and zero or more arguments (no shell)
1730
1763
  #
1764
+ # **Argument `command_line`**
1731
1765
  #
1732
- # In the first form, the string is taken as a command line that is subject to
1733
- # shell expansion before being executed.
1766
+ # String argument `command_line` is a command line to be passed to a shell; it
1767
+ # must begin with a shell reserved word, begin with a special built-in, or
1768
+ # contain meta characters:
1769
+ #
1770
+ # exec('if true; then echo "Foo"; fi') # Shell reserved word.
1771
+ # exec('echo') # Built-in.
1772
+ # exec('date > date.tmp') # Contains meta character.
1773
+ #
1774
+ # The command line may also contain arguments and options for the command:
1775
+ #
1776
+ # exec('echo "Foo"')
1777
+ #
1778
+ # Output:
1734
1779
  #
1735
- # The standard shell always means `"/bin/sh"` on Unix-like systems, otherwise,
1736
- # `ENV["RUBYSHELL"]` or `ENV["COMSPEC"]` on Windows and similar. The command is
1737
- # passed as an argument to the `"-c"` switch to the shell, except in the case of
1738
- # `COMSPEC`.
1780
+ # Foo
1739
1781
  #
1740
- # If the string from the first form (`exec("command")`) follows these simple
1741
- # rules:
1782
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
1783
+ # shell.
1742
1784
  #
1743
- # * no meta characters,
1744
- # * not starting with shell reserved word or special built-in,
1785
+ # Raises an exception if the new process could not execute.
1745
1786
  #
1787
+ # **Argument `exe_path`**
1746
1788
  #
1747
- # Ruby invokes the command directly without shell.
1789
+ # Argument `exe_path` is one of the following:
1748
1790
  #
1749
- # You can force shell invocation by adding ";" to the string (because ";" is a
1750
- # meta character).
1791
+ # * The string path to an executable to be called.
1792
+ # * A 2-element array containing the path to an executable and the string to
1793
+ # be used as the name of the executing process.
1751
1794
  #
1752
- # Note that this behavior is observable by pid obtained (return value of spawn()
1753
- # and IO#pid for IO.popen) is the pid of the invoked command, not shell.
1754
1795
  #
1755
- # In the second form (`exec("command1", "arg1", ...)`), the first is taken as a
1756
- # command name and the rest are passed as parameters to command with no shell
1757
- # expansion.
1796
+ # Example:
1758
1797
  #
1759
- # In the third form (`exec(["command", "argv0"], "arg1", ...)`), starting a
1760
- # two-element array at the beginning of the command, the first element is the
1761
- # command to be executed, and the second argument is used as the `argv[0]`
1762
- # value, which may show up in process listings.
1798
+ # exec('/usr/bin/date')
1763
1799
  #
1764
- # In order to execute the command, one of the `exec(2)` system calls are used,
1765
- # so the running command may inherit some of the environment of the original
1766
- # program (including open file descriptors).
1800
+ # Output:
1767
1801
  #
1768
- # This behavior is modified by the given `env` and `options` parameters. See
1769
- # ::spawn for details.
1802
+ # Sat Aug 26 09:38:00 AM CDT 2023
1770
1803
  #
1771
- # If the command fails to execute (typically Errno::ENOENT when it was not
1772
- # found) a SystemCallError exception is raised.
1804
+ # Ruby invokes the executable directly, with no shell and no shell expansion:
1773
1805
  #
1774
- # This method modifies process attributes according to given `options` before
1775
- # `exec(2)` system call. See ::spawn for more details about the given `options`.
1806
+ # exec('doesnt_exist') # Raises Errno::ENOENT
1776
1807
  #
1777
- # The modified attributes may be retained when `exec(2)` system call fails.
1808
+ # If one or more `args` is given, each is an argument or option to be passed to
1809
+ # the executable:
1778
1810
  #
1779
- # For example, hard resource limits are not restorable.
1811
+ # exec('echo', 'C*')
1812
+ # exec('echo', 'hello', 'world')
1780
1813
  #
1781
- # Consider to create a child process using ::spawn or Kernel#system if this is
1782
- # not acceptable.
1814
+ # Output:
1783
1815
  #
1784
- # exec "echo *" # echoes list of files in current directory
1785
- # # never get here
1816
+ # C*
1817
+ # hello world
1786
1818
  #
1787
- # exec "echo", "*" # echoes an asterisk
1788
- # # never get here
1819
+ # Raises an exception if the new process could not execute.
1789
1820
  #
1790
1821
  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
1791
1822
  | (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
@@ -1794,304 +1825,235 @@ module Kernel : BasicObject
1794
1825
 
1795
1826
  # <!--
1796
1827
  # rdoc-file=process.c
1797
- # - spawn([env,] command... [,options]) -> pid
1798
- # - Process.spawn([env,] command... [,options]) -> pid
1799
- # -->
1800
- # spawn executes specified command and return its pid.
1801
- #
1802
- # pid = spawn("tar xf ruby-2.0.0-p195.tar.bz2")
1803
- # Process.wait pid
1804
- #
1805
- # pid = spawn(RbConfig.ruby, "-eputs'Hello, world!'")
1806
- # Process.wait pid
1807
- #
1808
- # This method is similar to Kernel#system but it doesn't wait for the command to
1809
- # finish.
1810
- #
1811
- # The parent process should use Process.wait to collect the termination status
1812
- # of its child or use Process.detach to register disinterest in their status;
1813
- # otherwise, the operating system may accumulate zombie processes.
1814
- #
1815
- # spawn has bunch of options to specify process attributes:
1816
- #
1817
- # env: hash
1818
- # name => val : set the environment variable
1819
- # name => nil : unset the environment variable
1820
- #
1821
- # the keys and the values except for +nil+ must be strings.
1822
- # command...:
1823
- # commandline : command line string which is passed to the standard shell
1824
- # cmdname, arg1, ... : command name and one or more arguments (This form does not use the shell. See below for caveats.)
1825
- # [cmdname, argv0], arg1, ... : command name, argv[0] and zero or more arguments (no shell)
1826
- # options: hash
1827
- # clearing environment variables:
1828
- # :unsetenv_others => true : clear environment variables except specified by env
1829
- # :unsetenv_others => false : don't clear (default)
1830
- # process group:
1831
- # :pgroup => true or 0 : make a new process group
1832
- # :pgroup => pgid : join the specified process group
1833
- # :pgroup => nil : don't change the process group (default)
1834
- # create new process group: Windows only
1835
- # :new_pgroup => true : the new process is the root process of a new process group
1836
- # :new_pgroup => false : don't create a new process group (default)
1837
- # resource limit: resourcename is core, cpu, data, etc. See Process.setrlimit.
1838
- # :rlimit_resourcename => limit
1839
- # :rlimit_resourcename => [cur_limit, max_limit]
1840
- # umask:
1841
- # :umask => int
1842
- # redirection:
1843
- # key:
1844
- # FD : single file descriptor in child process
1845
- # [FD, FD, ...] : multiple file descriptor in child process
1846
- # value:
1847
- # FD : redirect to the file descriptor in parent process
1848
- # string : redirect to file with open(string, "r" or "w")
1849
- # [string] : redirect to file with open(string, File::RDONLY)
1850
- # [string, open_mode] : redirect to file with open(string, open_mode, 0644)
1851
- # [string, open_mode, perm] : redirect to file with open(string, open_mode, perm)
1852
- # [:child, FD] : redirect to the redirected file descriptor
1853
- # :close : close the file descriptor in child process
1854
- # FD is one of follows
1855
- # :in : the file descriptor 0 which is the standard input
1856
- # :out : the file descriptor 1 which is the standard output
1857
- # :err : the file descriptor 2 which is the standard error
1858
- # integer : the file descriptor of specified the integer
1859
- # io : the file descriptor specified as io.fileno
1860
- # file descriptor inheritance: close non-redirected non-standard fds (3, 4, 5, ...) or not
1861
- # :close_others => false : inherit
1862
- # current directory:
1863
- # :chdir => str
1864
- #
1865
- # The `cmdname, arg1, ...` form does not use the shell. However, on different
1866
- # OSes, different things are provided as built-in commands. An example of this
1867
- # is +'echo'+, which is a built-in on Windows, but is a normal program on Linux
1868
- # and Mac OS X. This means that `Process.spawn 'echo', '%Path%'` will display
1869
- # the contents of the `%Path%` environment variable on Windows, but
1870
- # `Process.spawn 'echo', '$PATH'` prints the literal `$PATH`.
1871
- #
1872
- # If a hash is given as `env`, the environment is updated by `env` before
1873
- # `exec(2)` in the child process. If a pair in `env` has nil as the value, the
1874
- # variable is deleted.
1875
- #
1876
- # # set FOO as BAR and unset BAZ.
1877
- # pid = spawn({"FOO"=>"BAR", "BAZ"=>nil}, command)
1878
- #
1879
- # If a hash is given as `options`, it specifies process group, create new
1880
- # process group, resource limit, current directory, umask and redirects for the
1881
- # child process. Also, it can be specified to clear environment variables.
1882
- #
1883
- # The `:unsetenv_others` key in `options` specifies to clear environment
1884
- # variables, other than specified by `env`.
1885
- #
1886
- # pid = spawn(command, :unsetenv_others=>true) # no environment variable
1887
- # pid = spawn({"FOO"=>"BAR"}, command, :unsetenv_others=>true) # FOO only
1888
- #
1889
- # The `:pgroup` key in `options` specifies a process group. The corresponding
1890
- # value should be true, zero, a positive integer, or nil. true and zero cause
1891
- # the process to be a process leader of a new process group. A non-zero positive
1892
- # integer causes the process to join the provided process group. The default
1893
- # value, nil, causes the process to remain in the same process group.
1894
- #
1895
- # pid = spawn(command, :pgroup=>true) # process leader
1896
- # pid = spawn(command, :pgroup=>10) # belongs to the process group 10
1897
- #
1898
- # The `:new_pgroup` key in `options` specifies to pass
1899
- # `CREATE_NEW_PROCESS_GROUP` flag to `CreateProcessW()` that is Windows API.
1900
- # This option is only for Windows. true means the new process is the root
1901
- # process of the new process group. The new process has CTRL+C disabled. This
1902
- # flag is necessary for `Process.kill(:SIGINT, pid)` on the subprocess.
1903
- # :new_pgroup is false by default.
1904
- #
1905
- # pid = spawn(command, :new_pgroup=>true) # new process group
1906
- # pid = spawn(command, :new_pgroup=>false) # same process group
1907
- #
1908
- # The `:rlimit_`*foo* key specifies a resource limit. *foo* should be one of
1909
- # resource types such as `core`. The corresponding value should be an integer or
1910
- # an array which have one or two integers: same as cur_limit and max_limit
1911
- # arguments for Process.setrlimit.
1912
- #
1913
- # cur, max = Process.getrlimit(:CORE)
1914
- # pid = spawn(command, :rlimit_core=>[0,max]) # disable core temporary.
1915
- # pid = spawn(command, :rlimit_core=>max) # enable core dump
1916
- # pid = spawn(command, :rlimit_core=>0) # never dump core.
1917
- #
1918
- # The `:umask` key in `options` specifies the umask.
1919
- #
1920
- # pid = spawn(command, :umask=>077)
1921
- #
1922
- # The :in, :out, :err, an integer, an IO and an array key specifies a
1923
- # redirection. The redirection maps a file descriptor in the child process.
1924
- #
1925
- # For example, stderr can be merged into stdout as follows:
1926
- #
1927
- # pid = spawn(command, :err=>:out)
1928
- # pid = spawn(command, 2=>1)
1929
- # pid = spawn(command, STDERR=>:out)
1930
- # pid = spawn(command, STDERR=>STDOUT)
1931
- #
1932
- # The hash keys specifies a file descriptor in the child process started by
1933
- # #spawn. :err, 2 and STDERR specifies the standard error stream (stderr).
1934
- #
1935
- # The hash values specifies a file descriptor in the parent process which
1936
- # invokes #spawn. :out, 1 and STDOUT specifies the standard output stream
1937
- # (stdout).
1938
- #
1939
- # In the above example, the standard output in the child process is not
1940
- # specified. So it is inherited from the parent process.
1828
+ # - spawn([env, ] command_line, options = {}) -> pid
1829
+ # - spawn([env, ] exe_path, *args, options = {}) -> pid
1830
+ # -->
1831
+ # Creates a new child process by doing one of the following in that process:
1941
1832
  #
1942
- # The standard input stream (stdin) can be specified by :in, 0 and STDIN.
1833
+ # * Passing string `command_line` to the shell.
1834
+ # * Invoking the executable at `exe_path`.
1943
1835
  #
1944
- # A filename can be specified as a hash value.
1945
1836
  #
1946
- # pid = spawn(command, :in=>"/dev/null") # read mode
1947
- # pid = spawn(command, :out=>"/dev/null") # write mode
1948
- # pid = spawn(command, :err=>"log") # write mode
1949
- # pid = spawn(command, [:out, :err]=>"/dev/null") # write mode
1950
- # pid = spawn(command, 3=>"/dev/null") # read mode
1837
+ # This method has potential security vulnerabilities if called with untrusted
1838
+ # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
1951
1839
  #
1952
- # For stdout and stderr (and combination of them), it is opened in write mode.
1953
- # Otherwise read mode is used.
1840
+ # Returns the process ID (pid) of the new process, without waiting for it to
1841
+ # complete.
1954
1842
  #
1955
- # For specifying flags and permission of file creation explicitly, an array is
1956
- # used instead.
1843
+ # To avoid zombie processes, the parent process should call either:
1957
1844
  #
1958
- # pid = spawn(command, :in=>["file"]) # read mode is assumed
1959
- # pid = spawn(command, :in=>["file", "r"])
1960
- # pid = spawn(command, :out=>["log", "w"]) # 0644 assumed
1961
- # pid = spawn(command, :out=>["log", "w", 0600])
1962
- # pid = spawn(command, :out=>["log", File::WRONLY|File::EXCL|File::CREAT, 0600])
1845
+ # * Process.wait, to collect the termination statuses of its children.
1846
+ # * Process.detach, to register disinterest in their status.
1963
1847
  #
1964
- # The array specifies a filename, flags and permission. The flags can be a
1965
- # string or an integer. If the flags is omitted or nil, File::RDONLY is assumed.
1966
- # The permission should be an integer. If the permission is omitted or nil, 0644
1967
- # is assumed.
1968
1848
  #
1969
- # If an array of IOs and integers are specified as a hash key, all the elements
1970
- # are redirected.
1849
+ # The new process is created using the [exec system
1850
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/e
1851
+ # xecve.html); it may inherit some of its environment from the calling program
1852
+ # (possibly including open file descriptors).
1971
1853
  #
1972
- # # stdout and stderr is redirected to log file.
1973
- # # The file "log" is opened just once.
1974
- # pid = spawn(command, [:out, :err]=>["log", "w"])
1854
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
1855
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
1975
1856
  #
1976
- # Another way to merge multiple file descriptors is [:child, fd]. [:child, fd]
1977
- # means the file descriptor in the child process. This is different from fd. For
1978
- # example, :err=>:out means redirecting child stderr to parent stdout. But
1979
- # :err=>[:child, :out] means redirecting child stderr to child stdout. They
1980
- # differ if stdout is redirected in the child process as follows.
1857
+ # Argument `options` is a hash of options for the new process; see [Execution
1858
+ # Options](rdoc-ref:Process@Execution+Options).
1981
1859
  #
1982
- # # stdout and stderr is redirected to log file.
1983
- # # The file "log" is opened just once.
1984
- # pid = spawn(command, :out=>["log", "w"], :err=>[:child, :out])
1860
+ # The first required argument is one of the following:
1985
1861
  #
1986
- # [:child, :out] can be used to merge stderr into stdout in IO.popen. In this
1987
- # case, IO.popen redirects stdout to a pipe in the child process and [:child,
1988
- # :out] refers the redirected stdout.
1862
+ # * `command_line` if it is a string, and if it begins with a shell reserved
1863
+ # word or special built-in, or if it contains one or more meta characters.
1864
+ # * `exe_path` otherwise.
1989
1865
  #
1990
- # io = IO.popen(["sh", "-c", "echo out; echo err >&2", :err=>[:child, :out]])
1991
- # p io.read #=> "out\nerr\n"
1992
1866
  #
1993
- # The `:chdir` key in `options` specifies the current directory.
1867
+ # **Argument `command_line`**
1994
1868
  #
1995
- # pid = spawn(command, :chdir=>"/var/tmp")
1869
+ # String argument `command_line` is a command line to be passed to a shell; it
1870
+ # must begin with a shell reserved word, begin with a special built-in, or
1871
+ # contain meta characters:
1872
+ #
1873
+ # spawn('if true; then echo "Foo"; fi') # => 798847 # Shell reserved word.
1874
+ # Process.wait # => 798847
1875
+ # spawn('echo') # => 798848 # Built-in.
1876
+ # Process.wait # => 798848
1877
+ # spawn('date > /tmp/date.tmp') # => 798879 # Contains meta character.
1878
+ # Process.wait # => 798849
1879
+ # spawn('date > /nop/date.tmp') # => 798882 # Issues error message.
1880
+ # Process.wait # => 798882
1881
+ #
1882
+ # The command line may also contain arguments and options for the command:
1883
+ #
1884
+ # spawn('echo "Foo"') # => 799031
1885
+ # Process.wait # => 799031
1886
+ #
1887
+ # Output:
1996
1888
  #
1997
- # spawn closes all non-standard unspecified descriptors by default. The
1998
- # "standard" descriptors are 0, 1 and 2. This behavior is specified by
1999
- # :close_others option. :close_others doesn't affect the standard descriptors
2000
- # which are closed only if :close is specified explicitly.
1889
+ # Foo
2001
1890
  #
2002
- # pid = spawn(command, :close_others=>true) # close 3,4,5,... (default)
2003
- # pid = spawn(command, :close_others=>false) # don't close 3,4,5,...
1891
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
1892
+ # shell.
2004
1893
  #
2005
- # :close_others is false by default for spawn and IO.popen.
1894
+ # Raises an exception if the new process could not execute.
2006
1895
  #
2007
- # Note that fds which close-on-exec flag is already set are closed regardless of
2008
- # :close_others option.
1896
+ # **Argument `exe_path`**
2009
1897
  #
2010
- # So IO.pipe and spawn can be used as IO.popen.
1898
+ # Argument `exe_path` is one of the following:
2011
1899
  #
2012
- # # similar to r = IO.popen(command)
2013
- # r, w = IO.pipe
2014
- # pid = spawn(command, :out=>w) # r, w is closed in the child process.
2015
- # w.close
1900
+ # * The string path to an executable to be called:
2016
1901
  #
2017
- # :close is specified as a hash value to close a fd individually.
1902
+ # spawn('/usr/bin/date') # Path to date on Unix-style system.
1903
+ # Process.wait
2018
1904
  #
2019
- # f = open(foo)
2020
- # system(command, f=>:close) # don't inherit f.
1905
+ # Output:
2021
1906
  #
2022
- # If a file descriptor need to be inherited, io=>io can be used.
1907
+ # Thu Aug 31 10:06:48 AM CDT 2023
2023
1908
  #
2024
- # # valgrind has --log-fd option for log destination.
2025
- # # log_w=>log_w indicates log_w.fileno inherits to child process.
2026
- # log_r, log_w = IO.pipe
2027
- # pid = spawn("valgrind", "--log-fd=#{log_w.fileno}", "echo", "a", log_w=>log_w)
2028
- # log_w.close
2029
- # p log_r.read
1909
+ # * A 2-element array containing the path to an executable and the string to
1910
+ # be used as the name of the executing process:
2030
1911
  #
2031
- # It is also possible to exchange file descriptors.
1912
+ # pid = spawn(['sleep', 'Hello!'], '1') # 2-element array.
1913
+ # p `ps -p #{pid} -o command=`
2032
1914
  #
2033
- # pid = spawn(command, :out=>:err, :err=>:out)
1915
+ # Output:
2034
1916
  #
2035
- # The hash keys specify file descriptors in the child process. The hash values
2036
- # specifies file descriptors in the parent process. So the above specifies
2037
- # exchanging stdout and stderr. Internally, `spawn` uses an extra file
2038
- # descriptor to resolve such cyclic file descriptor mapping.
1917
+ # "Hello! 1\n"
2039
1918
  #
2040
- # See Kernel.exec for the standard shell.
1919
+ #
1920
+ # Ruby invokes the executable directly, with no shell and no shell expansion.
1921
+ #
1922
+ # If one or more `args` is given, each is an argument or option to be passed to
1923
+ # the executable:
1924
+ #
1925
+ # spawn('echo', 'C*') # => 799392
1926
+ # Process.wait # => 799392
1927
+ # spawn('echo', 'hello', 'world') # => 799393
1928
+ # Process.wait # => 799393
1929
+ #
1930
+ # Output:
1931
+ #
1932
+ # C*
1933
+ # hello world
1934
+ #
1935
+ # Raises an exception if the new process could not execute.
2041
1936
  #
2042
1937
  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
2043
1938
  | (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
2044
1939
 
2045
1940
  # <!--
2046
1941
  # rdoc-file=process.c
2047
- # - system([env,] command... [,options], exception: false) -> true, false or nil
1942
+ # - system([env, ] command_line, options = {}, exception: false) -> true, false, or nil
1943
+ # - system([env, ] exe_path, *args, options = {}, exception: false) -> true, false, or nil
2048
1944
  # -->
2049
- # Executes *command...* in a subshell. *command...* is one of following forms.
1945
+ # Creates a new child process by doing one of the following in that process:
1946
+ #
1947
+ # * Passing string `command_line` to the shell.
1948
+ # * Invoking the executable at `exe_path`.
1949
+ #
2050
1950
  #
2051
1951
  # This method has potential security vulnerabilities if called with untrusted
2052
1952
  # input; see [Command Injection](rdoc-ref:command_injection.rdoc).
2053
1953
  #
2054
- # `commandline`
2055
- # : command line string which is passed to the standard shell
2056
- # `cmdname, arg1, ...`
2057
- # : command name and one or more arguments (no shell)
2058
- # `[cmdname, argv0], arg1, ...`
2059
- # : command name, `argv[0]` and zero or more arguments (no shell)
1954
+ # Returns:
2060
1955
  #
1956
+ # * `true` if the command exits with status zero.
1957
+ # * `false` if the exit status is a non-zero integer.
1958
+ # * `nil` if the command could not execute.
2061
1959
  #
2062
- # system returns `true` if the command gives zero exit status, `false` for non
2063
- # zero exit status. Returns `nil` if command execution fails. An error status is
2064
- # available in `$?`.
2065
1960
  #
2066
- # If the `exception: true` argument is passed, the method raises an exception
2067
- # instead of returning `false` or `nil`.
1961
+ # Raises an exception (instead of returning `false` or `nil`) if keyword
1962
+ # argument `exception` is set to `true`.
2068
1963
  #
2069
- # The arguments are processed in the same way as for Kernel#spawn.
1964
+ # Assigns the command's error status to `$?`.
2070
1965
  #
2071
- # The hash arguments, env and options, are same as #exec and #spawn. See
2072
- # Kernel#spawn for details.
1966
+ # The new process is created using the [system system
1967
+ # call](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/functions/s
1968
+ # ystem.html); it may inherit some of its environment from the calling program
1969
+ # (possibly including open file descriptors).
2073
1970
  #
2074
- # system("echo *")
2075
- # system("echo", "*")
1971
+ # Argument `env`, if given, is a hash that affects `ENV` for the new process;
1972
+ # see [Execution Environment](rdoc-ref:Process@Execution+Environment).
2076
1973
  #
2077
- # *produces:*
1974
+ # Argument `options` is a hash of options for the new process; see [Execution
1975
+ # Options](rdoc-ref:Process@Execution+Options).
1976
+ #
1977
+ # The first required argument is one of the following:
1978
+ #
1979
+ # * `command_line` if it is a string, and if it begins with a shell reserved
1980
+ # word or special built-in, or if it contains one or more meta characters.
1981
+ # * `exe_path` otherwise.
1982
+ #
1983
+ #
1984
+ # **Argument `command_line`**
1985
+ #
1986
+ # String argument `command_line` is a command line to be passed to a shell; it
1987
+ # must begin with a shell reserved word, begin with a special built-in, or
1988
+ # contain meta characters:
1989
+ #
1990
+ # system('if true; then echo "Foo"; fi') # => true # Shell reserved word.
1991
+ # system('echo') # => true # Built-in.
1992
+ # system('date > /tmp/date.tmp') # => true # Contains meta character.
1993
+ # system('date > /nop/date.tmp') # => false
1994
+ # system('date > /nop/date.tmp', exception: true) # Raises RuntimeError.
1995
+ #
1996
+ # Assigns the command's error status to `$?`:
1997
+ #
1998
+ # system('echo') # => true # Built-in.
1999
+ # $? # => #<Process::Status: pid 640610 exit 0>
2000
+ # system('date > /nop/date.tmp') # => false
2001
+ # $? # => #<Process::Status: pid 640742 exit 2>
2002
+ #
2003
+ # The command line may also contain arguments and options for the command:
2004
+ #
2005
+ # system('echo "Foo"') # => true
2006
+ #
2007
+ # Output:
2078
2008
  #
2079
- # config.h main.rb
2080
- # *
2009
+ # Foo
2081
2010
  #
2082
- # Error handling:
2011
+ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the
2012
+ # shell.
2083
2013
  #
2084
- # system("cat nonexistent.txt")
2085
- # # => false
2086
- # system("catt nonexistent.txt")
2087
- # # => nil
2014
+ # Raises an exception if the new process could not execute.
2088
2015
  #
2089
- # system("cat nonexistent.txt", exception: true)
2090
- # # RuntimeError (Command failed with exit 1: cat)
2091
- # system("catt nonexistent.txt", exception: true)
2092
- # # Errno::ENOENT (No such file or directory - catt)
2016
+ # **Argument `exe_path`**
2093
2017
  #
2094
- # See Kernel#exec for the standard shell.
2018
+ # Argument `exe_path` is one of the following:
2019
+ #
2020
+ # * The string path to an executable to be called.
2021
+ # * A 2-element array containing the path to an executable and the string to
2022
+ # be used as the name of the executing process.
2023
+ #
2024
+ #
2025
+ # Example:
2026
+ #
2027
+ # system('/usr/bin/date') # => true # Path to date on Unix-style system.
2028
+ # system('foo') # => nil # Command failed.
2029
+ #
2030
+ # Output:
2031
+ #
2032
+ # Mon Aug 28 11:43:10 AM CDT 2023
2033
+ #
2034
+ # Assigns the command's error status to `$?`:
2035
+ #
2036
+ # system('/usr/bin/date') # => true
2037
+ # $? # => #<Process::Status: pid 645605 exit 0>
2038
+ # system('foo') # => nil
2039
+ # $? # => #<Process::Status: pid 645608 exit 127>
2040
+ #
2041
+ # Ruby invokes the executable directly, with no shell and no shell expansion:
2042
+ #
2043
+ # system('doesnt_exist') # => nil
2044
+ #
2045
+ # If one or more `args` is given, each is an argument or option to be passed to
2046
+ # the executable:
2047
+ #
2048
+ # system('echo', 'C*') # => true
2049
+ # system('echo', 'hello', 'world') # => true
2050
+ #
2051
+ # Output:
2052
+ #
2053
+ # C*
2054
+ # hello world
2055
+ #
2056
+ # Raises an exception if the new process could not execute.
2095
2057
  #
2096
2058
  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)
2097
2059
  | (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)
@@ -2956,15 +2918,6 @@ module Kernel : BasicObject
2956
2918
  #
2957
2919
  # "my string".yield_self {|s| s.upcase } #=> "MY STRING"
2958
2920
  #
2959
- # Good usage for `then` is value piping in method chains:
2960
- #
2961
- # require 'open-uri'
2962
- # require 'json'
2963
- #
2964
- # construct_url(arguments).
2965
- # then {|url| URI(url).read }.
2966
- # then {|response| JSON.parse(response) }
2967
- #
2968
2921
  def yield_self: [X] () { (self) -> X } -> X
2969
2922
  | () -> Enumerator[self, untyped]
2970
2923