rbs 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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