diff --git a/.github/workflows/bundle-update.yml b/.github/workflows/bundle-update.yml index 5e4067690..7fe0bc6c4 100644 --- a/.github/workflows/bundle-update.yml +++ b/.github/workflows/bundle-update.yml @@ -16,7 +16,7 @@ jobs: - name: Set up Ruby uses: ruby/setup-ruby@v1 with: - ruby-version: '4.0.0-preview3' + ruby-version: '4.0' - name: Set up git run: | diff --git a/.github/workflows/c-check.yml b/.github/workflows/c-check.yml index 31d506089..8290f966c 100644 --- a/.github/workflows/c-check.yml +++ b/.github/workflows/c-check.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: - ruby-version: "4.0.0-preview3" + ruby-version: "4.0" bundler-cache: none - name: Set working directory as safe run: git config --global --add safe.directory $(pwd) diff --git a/.github/workflows/comments.yml b/.github/workflows/comments.yml index 53bba5174..3d0b8cff6 100644 --- a/.github/workflows/comments.yml +++ b/.github/workflows/comments.yml @@ -10,13 +10,13 @@ on: jobs: comments: runs-on: "ubuntu-latest" - env: - RUBY_COMMIT: v4.0.0-preview3 + # env: + # RUBY_COMMIT: v4.0.0-preview2 steps: - uses: actions/checkout@v6 - uses: ruby/setup-ruby@v1 with: - ruby-version: "4.0.0-preview3" + ruby-version: "4.0.0" bundler: none - name: Install dependencies run: | diff --git a/.github/workflows/ruby.yml b/.github/workflows/ruby.yml index cd65f49d7..30cead014 100644 --- a/.github/workflows/ruby.yml +++ b/.github/workflows/ruby.yml @@ -13,24 +13,24 @@ jobs: strategy: fail-fast: false matrix: - ruby: ['3.2', '3.3', '3.4', '4.0.0-preview3', head] + ruby: ['3.2', '3.3', '3.4', '4.0', head] rubyopt: [""] job: - test include: - ruby: head job: stdlib_test rubocop - - ruby: "4.0.0-preview3" + - ruby: "4.0" job: stdlib_test - - ruby: "4.0.0-preview3" + - ruby: "4.0" job: test rubyopt: "--enable-frozen-string-literal" - - ruby: "4.0.0-preview3" + - ruby: "4.0" job: stdlib_test rubyopt: "--enable-frozen-string-literal" - - ruby: "4.0.0-preview3" + - ruby: "4.0" job: rubocop validate test_doc build test_generate_stdlib raap - - ruby: "4.0.0-preview3" + - ruby: "4.0" job: typecheck_test env: RANDOMIZE_STDLIB_TEST_ORDER: "true" @@ -74,7 +74,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: ['4.0.0-preview3', head] + ruby: ['4.0', head] steps: - uses: actions/checkout@v6 - name: Install dependencies @@ -100,4 +100,3 @@ jobs: run: | bin/setup - run: bundle exec rake clean compile_c99 - diff --git a/bin/generate_docs.sh b/bin/generate_docs.sh index 59ef404d9..7ec18b8b4 100755 --- a/bin/generate_docs.sh +++ b/bin/generate_docs.sh @@ -3,7 +3,14 @@ set -ex if [ -z ${RUBY_COMMIT} ]; then - RUBY_COMMIT=v`ruby -e 'puts RUBY_VERSION.gsub(".", "_")'` + RUBY_COMMIT=v`ruby -e ' +case +when RUBY_VERSION >= "4.0.0" + puts RUBY_VERSION +else + puts RUBY_VERSION.gsub(".", "_") +end +'` fi if [ -z ${RBS_RDOC_BASE_DIR} ]; then diff --git a/core/array.rbs b/core/array.rbs index 739c693d6..887c1a6c9 100644 --- a/core/array.rbs +++ b/core/array.rbs @@ -2029,14 +2029,12 @@ class Array[unchecked out Elem] < Object # With a block given, calls the block with successive elements of the array; # returns the first element for which the block returns a truthy value: # - # (0..9).find {|element| element > 2} # => 3 + # [1, 3, 5].find {|element| element > 2} # => 3 # # If no such element is found, calls `if_none_proc` and returns its return # value. # - # (0..9).find(proc {false}) {|element| element > 12} # => false - # {foo: 0, bar: 1, baz: 2}.find {|key, value| key.start_with?('b') } # => [:bar, 1] - # {foo: 0, bar: 1, baz: 2}.find(proc {[]}) {|key, value| key.start_with?('c') } # => [] + # [1, 3, 5].find(proc {-1}) {|element| element > 12} # => -1 # # With no block given, returns an Enumerator. # @@ -3022,17 +3020,15 @@ class Array[unchecked out Elem] < Object # Returns the last element for which the block returns a truthy value. # # With a block given, calls the block with successive elements of the array in - # reverse order; returns the last element for which the block returns a truthy + # reverse order; returns the first element for which the block returns a truthy # value: # - # (0..9).rfind {|element| element < 5} # => 4 + # [1, 2, 3, 4, 5, 6].rfind {|element| element < 5} # => 4 # # If no such element is found, calls `if_none_proc` and returns its return # value. # - # (0..9).rfind(proc {false}) {|element| element < -2} # => false - # {foo: 0, bar: 1, baz: 2}.rfind {|key, value| key.start_with?('b') } # => [:baz, 2] - # {foo: 0, bar: 1, baz: 2}.rfind(proc {[]}) {|key, value| key.start_with?('c') } # => [] + # [1, 2, 3, 4].rfind(proc {0}) {|element| element < -2} # => 0 # # With no block given, returns an Enumerator. # diff --git a/core/comparable.rbs b/core/comparable.rbs index bffa53b9c..7e13673f3 100644 --- a/core/comparable.rbs +++ b/core/comparable.rbs @@ -55,19 +55,26 @@ module Comparable : _WithSpaceshipOperator # - # Compares two objects based on the receiver's `<=>` method, returning true if - # it returns a value less than 0. + # Returns whether `self` is "less than" `other`; equivalent to `(self <=> other) + # < 0`: + # + # 'foo' < 'foo' # => false + # 'foo' < 'food' # => true # def <: (untyped other) -> bool # - # Compares two objects based on the receiver's `<=>` method, returning true if - # it returns a value less than or equal to 0. + # Returns whether `self` is "less than or equal to" `other`; equivalent to + # `(self <=> other) <= 0`: + # + # 'foo' <= 'foo' # => true + # 'foo' <= 'food' # => true + # 'food' <= 'foo' # => false # def <=: (untyped other) -> bool diff --git a/core/complex.rbs b/core/complex.rbs index 3b4b4919f..0a2d31045 100644 --- a/core/complex.rbs +++ b/core/complex.rbs @@ -277,15 +277,16 @@ class Complex < Numeric # + # Compares `self` and `other`. + # # Returns: # - # * `self.real <=> object.real` if both of the following are true: + # * `self.real <=> other.real` if both of the following are true: # # * `self.imag == 0`. - # * `object.imag == 0`. # Always true if object is numeric but not - # complex. + # * `other.imag == 0` (always true if `other` is numeric but not complex). # # * `nil` otherwise. # @@ -298,6 +299,9 @@ class Complex < Numeric # Complex.rect(1) <=> Complex.rect(1, 1) # => nil # object.imag not zero. # Complex.rect(1) <=> 'Foo' # => nil # object.imag not defined. # + # Class Complex includes module Comparable, each of whose methods uses + # Complex#<=> for comparison. + # def <=>: (untyped) -> Integer? # # Raises an exception in the fiber at the point at which the last `Fiber.yield` - # was called. If the fiber has not been started or has already run to - # completion, raises `FiberError`. If the fiber is yielding, it is resumed. If - # it is transferring, it is transferred into. But if it is resuming, raises - # `FiberError`. - # - # With no arguments, raises a `RuntimeError`. With a single `String` argument, - # raises a `RuntimeError` with the string as a message. Otherwise, the first - # parameter should be the name of an `Exception` class (or an object that - # returns an `Exception` object when sent an `exception` message). The optional - # second parameter sets the message associated with the exception, and the third - # parameter is an array of callback information. Exceptions are caught by the - # `rescue` clause of `begin...end` blocks. + # was called. + # + # f = Fiber.new { + # puts "Before the yield" + # Fiber.yield 1 # -- exception will be raised here + # puts "After the yield" + # } + # + # p f.resume + # f.raise "Gotcha" + # + # Output + # + # Before the first yield + # 1 + # t.rb:8:in 'Fiber.yield': Gotcha (RuntimeError) + # from t.rb:8:in 'block in
' + # + # If the fiber has not been started or has already run to completion, raises + # `FiberError`. If the fiber is yielding, it is resumed. If it is transferring, + # it is transferred into. But if it is resuming, raises `FiberError`. # # Raises `FiberError` if called on a Fiber belonging to another `Thread`. # - # See Kernel#raise for more information. + # See Kernel#raise for more information on arguments. # def raise: (?string msg, ?cause: Exception?) -> untyped | (_Exception, ?string msg, ?Array[string] | Array[Thread::Backtrace::Location] | nil backtrace, ?cause: Exception?) -> untyped diff --git a/core/file.rbs b/core/file.rbs index 6a31cbcbd..c77952cf2 100644 --- a/core/file.rbs +++ b/core/file.rbs @@ -2455,16 +2455,31 @@ class File::Stat < Object # - # Compares File::Stat objects by comparing their respective modification times. + # Compares `self` and `other`, by comparing their modification times; that is, + # by comparing `self.mtime` and `other.mtime`. # - # `nil` is returned if `other_stat` is not a File::Stat object + # Returns: # - # f1 = File.new("f1", "w") - # sleep 1 - # f2 = File.new("f2", "w") - # f1.stat <=> f2.stat #=> -1 + # * `-1`, if `self.mtime` is earlier. + # * `0`, if the two values are equal. + # * `1`, if `self.mtime` is later. + # * `nil`, if `other` is not a File::Stat object. + # + # Examples: + # + # stat0 = File.stat('README.md') + # stat1 = File.stat('NEWS.md') + # stat0.mtime # => 2025-12-20 15:33:05.6972341 -0600 + # stat1.mtime # => 2025-12-20 16:02:08.2672945 -0600 + # stat0 <=> stat1 # => -1 + # stat0 <=> stat0.dup # => 0 + # stat1 <=> stat0 # => 1 + # stat0 <=> :foo # => nil + # + # Class File::Stat includes module Comparable, each of whose methods uses + # File::Stat#<=> for comparison. # def <=>: (File::Stat other) -> Integer | (untyped) -> nil diff --git a/core/float.rbs b/core/float.rbs index aab9f1a92..3e779cc6a 100644 --- a/core/float.rbs +++ b/core/float.rbs @@ -382,7 +382,8 @@ class Float < Numeric # rdoc-file=numeric.c # - self < other -> true or false # --> - # Returns `true` if `self` is numerically less than `other`: + # Returns whether the value of `self` is less than the value of `other`; `other` + # must be numeric, but may not be Complex: # # 2.0 < 3 # => true # 2.0 < 3.0 # => true @@ -397,7 +398,8 @@ class Float < Numeric # rdoc-file=numeric.c # - self <= other -> true or false # --> - # Returns `true` if `self` is numerically less than or equal to `other`: + # Returns whether the value of `self` is less than or equal to the value of + # `other`; `other` must be numeric, but may not be Complex: # # 2.0 <= 3 # => true # 2.0 <= 3.0 # => true @@ -411,30 +413,32 @@ class Float < Numeric # - # Returns a value that depends on the numeric relation between `self` and - # `other`: + # Compares `self` and `other`. # - # * -1, if `self` is less than `other`. - # * 0, if `self` is equal to `other`. - # * 1, if `self` is greater than `other`. + # Returns: + # + # * `-1`, if `self` is less than `other`. + # * `0`, if `self` is equal to `other`. + # * `1`, if `self` is greater than `other`. # * `nil`, if the two values are incommensurate. # # Examples: # + # 2.0 <=> 2.1 # => -1 # 2.0 <=> 2 # => 0 # 2.0 <=> 2.0 # => 0 # 2.0 <=> Rational(2, 1) # => 0 # 2.0 <=> Complex(2, 0) # => 0 # 2.0 <=> 1.9 # => 1 - # 2.0 <=> 2.1 # => -1 # 2.0 <=> 'foo' # => nil # - # This is the basis for the tests in the Comparable module. - # # `Float::NAN <=> Float::NAN` returns an implementation-dependent value. # + # Class Float includes module Comparable, each of whose methods uses Float#<=> + # for comparison. + # def <=>: (Numeric) -> Integer? # - # Returns `true` if the entries of `self` are a proper subset of the entries of - # `other_hash`, `false` otherwise: + # Returns whether the entries of `self` are a proper subset of the entries of + # `other`: # # h = {foo: 0, bar: 1} # h < {foo: 0, bar: 1, baz: 2} # => true # Proper subset. @@ -558,10 +558,9 @@ class Hash[unchecked out K, unchecked out V] < Object # - # Returns `true` if the entries of `self` are a subset of the entries of - # `other_hash`, `false` otherwise: + # Returns whether the entries of `self` are a subset of the entries of `other`: # # h0 = {foo: 0, bar: 1} # h1 = {foo: 0, bar: 1, baz: 2} diff --git a/core/integer.rbs b/core/integer.rbs index 7baceef79..e1536f5c3 100644 --- a/core/integer.rbs +++ b/core/integer.rbs @@ -338,15 +338,14 @@ class Integer < Numeric # rdoc-file=numeric.c # - self < other -> true or false # --> - # Returns `true` if the value of `self` is less than that of `other`: + # Returns whether the value of `self` is less than the value of `other`; `other` + # must be numeric, but may not be Complex: # - # 1 < 0 # => false - # 1 < 1 # => false - # 1 < 2 # => true - # 1 < 0.5 # => false - # 1 < Rational(1, 2) # => false - # - # Raises an exception if the comparison cannot be made. + # 1 < 0 # => false + # 1 < 1 # => false + # 1 < 2 # => true + # 1 < 0.5 # => false + # 1 < Rational(1, 2) # => false # def <: (Numeric) -> bool @@ -369,44 +368,46 @@ class Integer < Numeric # - # Returns `true` if the value of `self` is less than or equal to that of - # `other`: + # Returns whether the value of `self` is less than or equal to the value of + # `other`; `other` must be numeric, but may not be Complex: # - # 1 <= 0 # => false - # 1 <= 1 # => true - # 1 <= 2 # => true - # 1 <= 0.5 # => false - # 1 <= Rational(1, 2) # => false + # 1 <= 0 # => false + # 1 <= 1 # => true + # 1 <= 2 # => true + # 1 <= 0.5 # => false + # 1 <= Rational(1, 2) # => false # - # Raises an exception if the comparison cannot be made. + # Raises an exception if the comparison cannot be made. # def <=: (Numeric) -> bool # + # Compares `self` and `other`. + # # Returns: # - # * -1, if `self` is less than `other`. - # * 0, if `self` is equal to `other`. - # * 1, if `self` is greater then `other`. + # * `-1`, if `self` is less than `other`. + # * `0`, if `self` is equal to `other`. + # * `1`, if `self` is greater then `other`. # * `nil`, if `self` and `other` are incomparable. # # Examples: # # 1 <=> 2 # => -1 # 1 <=> 1 # => 0 - # 1 <=> 0 # => 1 - # 1 <=> 'foo' # => nil - # # 1 <=> 1.0 # => 0 # 1 <=> Rational(1, 1) # => 0 # 1 <=> Complex(1, 0) # => 0 + # 1 <=> 0 # => 1 + # 1 <=> 'foo' # => nil # - # This method is the basis for comparisons in module Comparable. + # Class Integer includes module Comparable, each of whose methods uses + # Integer#<=> for comparison. # def <=>: (Integer | Rational) -> Integer | (untyped) -> Integer? diff --git a/core/io/buffer.rbs b/core/io/buffer.rbs index e7f3ed0fd..a73b35f86 100644 --- a/core/io/buffer.rbs +++ b/core/io/buffer.rbs @@ -64,9 +64,9 @@ class IO # # File.write('test.txt', 'test data') # # => 9 - # buffer = IO::Buffer.map(File.open('test.txt')) + # buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::READONLY) # # => - # # # + # # # # # ... # buffer.get_string(5, 2) # read 2 bytes, starting from offset 5 # # => "da" @@ -113,7 +113,7 @@ class IO # buffer.get_string(0, 1) # # => "t" # string - # # => "best" + # # => "test" # # buffer.resize(100) # # in `resize': Cannot resize external buffer! (IO::Buffer::AccessError) diff --git a/core/kernel.rbs b/core/kernel.rbs index 9a50d9684..af1878c54 100644 --- a/core/kernel.rbs +++ b/core/kernel.rbs @@ -1004,6 +1004,8 @@ module Kernel : BasicObject # With argument `exception` not given, argument `message` and keyword argument # `cause` may be given, but argument `backtrace` may not be given. # + # `cause` can not be given as an only argument. + # def self?.fail: () -> bot | (string message, ?cause: Exception?) -> bot | (_Exception exception, ?_ToS? message, ?String | Array[String] | Array[Thread::Backtrace::Location] | nil backtrace, ?cause: Exception?) -> bot @@ -1110,6 +1112,8 @@ module Kernel : BasicObject # With argument `exception` not given, argument `message` and keyword argument # `cause` may be given, but argument `backtrace` may not be given. # + # `cause` can not be given as an only argument. + # alias raise fail alias self.raise self.fail diff --git a/core/method.rbs b/core/method.rbs index aa8224c2f..e2bd40899 100644 --- a/core/method.rbs +++ b/core/method.rbs @@ -124,7 +124,9 @@ class Method # # Invokes the *meth* with the specified arguments, returning the method's return # value. @@ -133,23 +135,32 @@ class Method # m.call(3) #=> 15 # m.call(20) #=> 32 # + # Using Method#=== allows a method object to be the target of a `when` clause in + # a case statement. + # + # require 'prime' + # + # case 1373 + # when Prime.method(:prime?) + # # ... + # end + # def call: (?) -> untyped # - # Returns a proc that is the composition of this method and the given *g*. The - # returned proc takes a variable number of arguments, calls *g* with them then - # calls this method with the result. + # Returns a proc that is the composition of the given `g` and this method. # - # def f(x) - # x * x - # end + # The returned proc takes a variable number of arguments. It first calls `g` + # with the arguments, then calls `self` with the return value of `g`. + # + # def f(ary) = ary << 'in f' # # f = self.method(:f) - # g = proc {|x| x + x } - # p (f << g).call(2) #=> 16 + # g = proc { |ary| ary << 'in proc' } + # (f << g).call([]) # => ["in proc", "in f"] # def <<: (Proc::_Callable g) -> Proc @@ -161,23 +172,32 @@ class Method # m.call(3) #=> 15 # m.call(20) #=> 32 # + # Using Method#=== allows a method object to be the target of a `when` clause in + # a case statement. + # + # require 'prime' + # + # case 1373 + # when Prime.method(:prime?) + # # ... + # end + # alias === call # - # Returns a proc that is the composition of this method and the given *g*. The - # returned proc takes a variable number of arguments, calls this method with - # them then calls *g* with the result. + # Returns a proc that is the composition of this method and the given `g`. # - # def f(x) - # x * x - # end + # The returned proc takes a variable number of arguments. It first calls `self` + # with the arguments, then calls `g` with the return value of `self`. + # + # def f(ary) = ary << 'in f' # # f = self.method(:f) - # g = proc {|x| x + x } - # p (f >> g).call(2) #=> 8 + # g = proc { |ary| ary << 'in proc' } + # (f >> g).call([]) # => ["in f", "in proc"] # def >>: (Proc::_Callable g) -> Proc @@ -189,6 +209,16 @@ class Method # m.call(3) #=> 15 # m.call(20) #=> 32 # + # Using Method#=== allows a method object to be the target of a `when` clause in + # a case statement. + # + # require 'prime' + # + # case 1373 + # when Prime.method(:prime?) + # # ... + # end + # alias [] call # - # Returns true if *mod* is a subclass of *other*. Returns `false` if *mod* is - # the same as *other* or *mod* is an ancestor of *other*. Returns `nil` if - # there's no relationship between the two. (Think of the relationship in terms - # of the class definition: "class A < B" implies "A < B".) + # Returns whether `self` is a subclass of `other`, or `nil` if there is no + # relationship between the two: + # + # Float < Numeric # => true + # Numeric < Float # => false + # Float < Float # => false + # Float < Hash # => nil # def <: (Module other) -> bool? @@ -135,13 +138,15 @@ class Module < Object # + # Compares `self` and `other`. + # # Returns: # - # * `-1`, if `self` includes `object`, if or `self` is a subclass of `object`. - # * `0`, if `self` and `object` are the same. - # * `1`, if `object` includes `self`, or if `object` is a subclass of `self`. + # * `-1`, if `self` includes `other`, if or `self` is a subclass of `other`. + # * `0`, if `self` and `other` are the same. + # * `1`, if `other` includes `self`, or if `other` is a subclass of `self`. # * `nil`, if none of the above is true. # # Examples: @@ -152,8 +157,10 @@ class Module < Object # Enumerable <=> Array # => 1 # # Class File is a subclass of class IO. # File <=> IO # => -1 - # IO <=> File # => 1 # File <=> File # => 0 + # IO <=> File # => 1 + # # Class File has no relationship to class String. + # File <=> String # => nil # def <=>: (untyped other) -> Integer? @@ -1647,7 +1654,7 @@ class Module < Object # m.name #=> nil # # c = Class.new - # c.set_temporary_name("MyClass(with description)") + # c.set_temporary_name("MyClass(with description)") # => MyClass(with description) # # c.new # => # # diff --git a/core/numeric.rbs b/core/numeric.rbs index 0928b38db..81aeb7aa4 100644 --- a/core/numeric.rbs +++ b/core/numeric.rbs @@ -220,7 +220,15 @@ class Numeric # rdoc-file=numeric.c # - self <=> other -> zero or nil # --> - # Returns zero if `self` is the same as `other`, `nil` otherwise. + # Compares `self` and `other`. + # + # Returns: + # + # * Zero, if `self` is the same as `other`. + # * `nil`, otherwise. + # + # Class Numeric includes module Comparable, each of whose methods uses + # Numeric#<=> for comparison. # # No subclass in the Ruby Core or Standard Library uses this implementation. # diff --git a/core/proc.rbs b/core/proc.rbs index ec0cc3af1..bdd88d92b 100644 --- a/core/proc.rbs +++ b/core/proc.rbs @@ -379,9 +379,9 @@ class Proc def clone: () -> self # - # Invokes the block, setting the block's parameters to the values in *params* - # using something close to method calling semantics. Returns the value of the - # last expression evaluated in the block. + # Invokes the block, setting the block's parameters to the arguments using + # something close to method calling semantics. Returns the value of the last + # expression evaluated in the block. # # a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } } # a_proc.call(9, 1, 2, 3) #=> [9, 18, 27] @@ -408,9 +408,9 @@ class Proc alias === call # - # Invokes the block, setting the block's parameters to the values in *params* - # using something close to method calling semantics. Returns the value of the - # last expression evaluated in the block. + # Invokes the block, setting the block's parameters to the arguments using + # something close to method calling semantics. Returns the value of the last + # expression evaluated in the block. # # a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } } # a_proc.call(9, 1, 2, 3) #=> [9, 18, 27] @@ -591,14 +591,13 @@ class Proc # - # Invokes the block, setting the block's parameters to the values in *params* - # using something close to method calling semantics. Returns the value of the - # last expression evaluated in the block. + # Invokes the block, setting the block's parameters to the arguments using + # something close to method calling semantics. Returns the value of the last + # expression evaluated in the block. # # a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } } # a_proc.call(9, 1, 2, 3) #=> [9, 18, 27] @@ -625,9 +624,9 @@ class Proc def call: (?) -> untyped # - # Invokes the block, setting the block's parameters to the values in *params* - # using something close to method calling semantics. Returns the value of the - # last expression evaluated in the block. + # Invokes the block, setting the block's parameters to the arguments using + # something close to method calling semantics. Returns the value of the last + # expression evaluated in the block. # # a_proc = Proc.new {|scalar, *values| values.map {|value| value*scalar } } # a_proc.call(9, 1, 2, 3) #=> [9, 18, 27] diff --git a/core/ractor.rbs b/core/ractor.rbs index b8b34e624..3ebf79541 100644 --- a/core/ractor.rbs +++ b/core/ractor.rbs @@ -1,5 +1,5 @@ # -# Ractor.new makes a new Ractor, which can run in parallel. +# Ractor.new creates a new Ractor, which can run in parallel with other ractors. # # # The simplest ractor # r = Ractor.new {puts "I am in Ractor!"} @@ -10,10 +10,10 @@ # to this: across ractors, thread-safety concerns such as data-races and # race-conditions are not possible. The other benefit is parallelism. # -# To achieve this, object sharing is limited across ractors. For example, unlike -# in threads, ractors can't access all the objects available in other ractors. -# Even objects normally available through variables in the outer scope are -# prohibited from being used across ractors. +# To achieve this, object sharing is limited across ractors. Unlike in threads, +# ractors can't access all the objects available in other ractors. For example, +# objects normally available through variables in the outer scope are prohibited +# from being used across ractors. # # a = 1 # r = Ractor.new {puts "I am in Ractor! a=#{a}"} @@ -24,16 +24,16 @@ # a = 1 # r = Ractor.new(a) { |a1| puts "I am in Ractor! a=#{a1}"} # -# On CRuby (the default implementation), Global Virtual Machine Lock (GVL) is -# held per ractor, so ractors can perform in parallel without locking each -# other. This is unlike the situation with threads on CRuby. +# On CRuby (the default implementation), the Global Virtual Machine Lock (GVL) +# is held per ractor, so ractors can run in parallel. This is unlike the +# situation with threads on CRuby. # # Instead of accessing shared state, objects should be passed to and from # ractors by sending and receiving them as messages. # # a = 1 # r = Ractor.new do -# a_in_ractor = receive # receive blocks until somebody passes a message +# a_in_ractor = receive # receive blocks the Thread until our default port gets sent a message # puts "I am in Ractor! a=#{a_in_ractor}" # end # r.send(a) # pass it @@ -46,15 +46,15 @@ # # ## Shareable and unshareable objects # -# When an object is sent to and from a ractor, it's important to understand -# whether the object is shareable or unshareable. Most Ruby objects are -# unshareable objects. Even frozen objects can be unshareable if they contain -# (through their instance variables) unfrozen objects. +# When an object is sent to a ractor, it's important to understand whether the +# object is shareable or unshareable. Most Ruby objects are unshareable objects. +# Even frozen objects can be unshareable if they contain (through their instance +# variables) unfrozen objects. # -# Shareable objects are those which can be used by several threads without -# compromising thread-safety, for example numbers, `true` and `false`. +# Shareable objects are those which can be used by several ractors at once +# without compromising thread-safety, for example numbers, `true` and `false`. # Ractor.shareable? allows you to check this, and Ractor.make_shareable tries to -# make the object shareable if it's not already, and gives an error if it can't +# make the object shareable if it's not already and gives an error if it can't # do it. # # Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are shareable @@ -70,13 +70,13 @@ # ary[0].frozen? #=> true # ary[1].frozen? #=> true # -# When a shareable object is sent (via #send or Ractor.yield), no additional -# processing occurs on it. It just becomes usable by both ractors. When an -# unshareable object is sent, it can be either *copied* or *moved*. The first is -# the default, and it copies the object fully by deep cloning (Object#clone) the -# non-shareable parts of its structure. +# When a shareable object is sent via #send, no additional processing occurs on +# it and it becomes usable by both ractors. When an unshareable object is sent, +# it can be either *copied* or *moved*. Copying is the default, and it copies +# the object fully by deep cloning (Object#clone) the non-shareable parts of its +# structure. # -# data = ['foo', 'bar'.freeze] +# data = ['foo'.dup, 'bar'.freeze] # r = Ractor.new do # data2 = Ractor.receive # puts "In ractor: #{data2.object_id}, #{data2[0].object_id}, #{data2[1].object_id}" @@ -87,8 +87,8 @@ # # This will output something like: # -# In ractor: 340, 360, 320 -# Outside : 380, 400, 320 +# In ractor: 8, 16, 24 +# Outside : 32, 40, 24 # # Note that the object ids of the array and the non-frozen string inside the # array have changed in the ractor because they are different objects. The @@ -115,14 +115,14 @@ # Outside: moved? true # test.rb:9:in `method_missing': can not send any methods to a moved object (Ractor::MovedError) # -# Notice that even `inspect` (and more basic methods like `__id__`) is +# Notice that even `inspect` and more basic methods like `__id__` are # inaccessible on a moved object. # -# `Class` and `Module` objects are shareable so the class/module definitions are -# shared between ractors. Ractor objects are also shareable. All operations on -# shareable objects are thread-safe, so the thread-safety property will be kept. -# We can not define mutable shareable objects in Ruby, but C extensions can -# introduce them. +# `Class` and `Module` objects are shareable and their class/module definitions +# are shared between ractors. Ractor objects are also shareable. All operations +# on shareable objects are thread-safe across ractors. Defining mutable, +# shareable objects in Ruby is not possible, but C extensions can introduce +# them. # # It is prohibited to access (get) instance variables of shareable objects in # other ractors if the values of the variables aren't shareable. This can occur @@ -189,14 +189,15 @@ # ## Note on code examples # # In the examples below, sometimes we use the following method to wait for -# ractors that are not currently blocked to finish (or to make progress). +# ractors to make progress or finish. # # def wait # sleep(0.1) # end # -# It is **only for demonstration purposes** and shouldn't be used in a real -# code. Most of the time, #join is used to wait for ractors to finish. +# This is **only for demonstration purposes** and shouldn't be used in a real +# code. Most of the time, #join is used to wait for ractors to finish and +# Ractor.receive is used to wait for messages. # # ## Reference # @@ -215,7 +216,7 @@ class Ractor # rdoc-file=ractor.rb # - [](sym) # --> - # get a value from ractor-local storage of current Ractor + # Gets a value from ractor-local storage for the current Ractor. # def self.[]: (Symbol) -> untyped @@ -223,7 +224,7 @@ class Ractor # rdoc-file=ractor.rb # - []=(sym, val) # --> - # set a value in ractor-local storage of current Ractor + # Sets a value in ractor-local storage for the current Ractor. # def self.[]=: (Symbol, untyped) -> untyped @@ -231,7 +232,7 @@ class Ractor # rdoc-file=ractor.rb # - count() # --> - # Returns the number of Ractors currently running or blocking (waiting). + # Returns the number of ractors currently running or blocking (waiting). # # Ractor.count #=> 1 # r = Ractor.new(name: 'example') { Ractor.receive } @@ -256,7 +257,7 @@ class Ractor # rdoc-file=ractor.rb # - main() # --> - # returns main ractor + # Returns the main ractor. # def self.main: () -> Ractor @@ -264,7 +265,7 @@ class Ractor # rdoc-file=ractor.rb # - main?() # --> - # return true if the current ractor is main ractor + # Returns true if the current ractor is the main ractor. # def self.main?: () -> boolish @@ -272,7 +273,7 @@ class Ractor # rdoc-file=ractor.rb # - Ractor.make_shareable(obj, copy: false) -> shareable_obj # --> - # Make `obj` shareable between ractors. + # Makes `obj` shareable between ractors. # # `obj` and all the objects it refers to will be frozen, unless they are already # shareable. @@ -311,10 +312,10 @@ class Ractor # rdoc-file=ractor.rb # - Ractor.new(*args, name: nil) {|*args| block } -> ractor # --> - # Create a new Ractor with args and a block. + # Creates a new Ractor with args and a block. # - # The given block (Proc) will be isolated (can't access any outer variables). - # `self` inside the block will refer to the current Ractor. + # The given block (Proc) is isolated (can't access any outer variables). `self` + # inside the block will refer to the current Ractor. # # r = Ractor.new { puts "Hi, I am #{self.inspect}" } # r.join @@ -346,7 +347,7 @@ class Ractor # rdoc-file=ractor.rb # - Ractor.receive -> obj # --> - # Receive a message from the default port. + # Receives a message from the current ractor's default port. # def self.receive: () -> untyped @@ -359,9 +360,48 @@ class Ractor # - # TBD + # Blocks the current Thread until one of the given ports has received a message. + # Returns an array of two elements where the first element is the Port and the + # second is the received object. This method can also accept Ractor objects + # themselves, and in that case will wait until one has terminated and return a + # two-element array where the first element is the ractor and the second is its + # termination value. + # + # p1, p2 = Ractor::Port.new, Ractor::Port.new + # ps = [p1, p2] + # rs = 2.times.map do |i| + # Ractor.new(ps.shift, i) do |p, i| + # sleep rand(0.99) + # p.send("r#{i}") + # sleep rand(0.99) + # "r#{i} done" + # end + # end + # + # waiting_on = [p1, p2, *rs] + # until waiting_on.empty? + # received_on, obj = Ractor.select(*waiting_on) + # waiting_on.delete(received_on) + # puts obj + # end + # + # # r0 + # # r1 + # # r1 done + # # r0 done + # + # The following example is almost equivalent to `ractors.map(&:value)` except + # the thread is unblocked when any of the ractors has terminated as opposed to + # waiting for their termination in the array element order. + # + # values = [] + # until ractors.empty? + # r, val = Ractor.select(*ractors) + # ractors.delete(r) + # values << val + # end # def self.select: (?) -> Array[untyped] @@ -371,7 +411,7 @@ class Ractor # --> # Checks if the object is shareable by ractors. # - # Ractor.shareable?(1) #=> true -- numbers and other immutable basic values are frozen + # Ractor.shareable?(1) #=> true -- numbers are shareable # Ractor.shareable?('foo') #=> false, unless the string is frozen due to # frozen_string_literal: true # Ractor.shareable?('foo'.freeze) #=> true # @@ -384,16 +424,17 @@ class Ractor # rdoc-file=ractor.rb # - Ractor.shareable_proc(self: nil){} -> shareable proc # --> - # It returns shareable Proc object. The Proc object is shareable and the self in - # a block will be replaced with the value passed via `self:` keyword. + # Returns a shareable copy of the given block's Proc. The value of `self` in the + # Proc will be replaced with the value passed via the `self:` keyword, or `nil` + # if not given. # - # In a shareable Proc, you can not access to the outer variables. + # In a shareable Proc, access to any outer variables if prohibited. # # a = 42 # Ractor.shareable_proc{ p a } # #=> can not isolate a Proc because it accesses outer variables (a). (ArgumentError) # - # The `self` should be a shareable object + # The value of `self` in the Proc must be a shareable object. # # Ractor.shareable_proc(self: self){} # #=> self should be shareable: main (Ractor::IsolationError) @@ -403,9 +444,9 @@ class Ractor # - # Same as Ractor.shareable_proc, but returns lambda proc. + # Same as Ractor.shareable_proc, but returns a lambda Proc. # def self.shareable_lambda: [T] () { (?) [self: nil] -> T } -> ^(?) [self: nil] -> T | [T, S] (self: S) { (?) [self: S] -> T } -> ^(?) [self: S] -> T @@ -414,9 +455,9 @@ class Ractor # rdoc-file=ractor.rb # - Ractor.store_if_absent(key){ init_block } # --> - # If the corresponding value is not set, yield a value with init_block and store - # the value in thread-safe manner. This method returns corresponding stored - # value. + # If the corresponding ractor-local value is not set, yields a value with + # init_block and stores the value in a thread-safe manner. This method returns + # the stored value. # # (1..10).map{ # Thread.new(it){|i| @@ -438,7 +479,7 @@ class Ractor # rdoc-file=ractor.rb # - [](sym) # --> - # get a value from ractor-local storage for current Ractor Obsolete and use + # Gets a value from ractor-local storage for the current Ractor. Obsolete, use # Ractor.[] instead. # %a{deprecated: Use Ractor.[] instead} @@ -448,7 +489,7 @@ class Ractor # rdoc-file=ractor.rb # - []=(sym, val) # --> - # set a value in ractor-local storage for current Ractor Obsolete and use + # Sets a value in ractor-local storage for the current Ractor. Obsolete, use # Ractor.[]= instead. # %a{deprecated: Use Ractor.[]= instead} @@ -458,7 +499,7 @@ class Ractor # rdoc-file=ractor.rb # - ractor.default_port -> port object # --> - # return default port of the Ractor. + # Returns the default port of the Ractor. # def default_port: () -> Port[untyped] @@ -473,13 +514,13 @@ class Ractor # rdoc-file=ractor.rb # - ractor.join -> self # --> - # Wait for the termination of the Ractor. If the Ractor was aborted (terminated - # with an exception), Ractor#value is called to raise an exception. + # Waits for the termination of the Ractor. If the Ractor was aborted (terminated + # by an unhandled exception), the exception is raised in the current ractor. # # Ractor.new{}.join #=> ractor # # Ractor.new{ raise "foo" }.join - # #=> raise an exception "foo (RuntimeError)" + # #=> raises the exception "foo (RuntimeError)" # def join: () -> self @@ -487,7 +528,7 @@ class Ractor # rdoc-file=ractor.rb # - name() # --> - # The name set in Ractor.new, or `nil`. + # Returns the name set in Ractor.new, or `nil`. # def name: () -> String? @@ -495,26 +536,27 @@ class Ractor # rdoc-file=ractor.rb # - ractor.monitor(port) -> self # --> - # Register port as a monitoring port. If the ractor terminated, the port - # received a Symbol object. :exited will be sent if the ractor terminated - # without an exception. :aborted will be sent if the ractor terminated with a - # exception. + # Registers the port as a monitoring port for this ractor. When the ractor + # terminates, the port receives a Symbol object. + # + # * `:exited` is sent if the ractor terminates without an unhandled exception. + # * `:aborted` is sent if the ractor terminates by an unhandled exception. # - # r = Ractor.new{ some_task() } - # r.monitor(port = Ractor::Port.new) - # port.receive #=> :exited and r is terminated + # r = Ractor.new{ some_task() } + # r.monitor(port = Ractor::Port.new) + # port.receive #=> :exited and r is terminated # - # r = Ractor.new{ raise "foo" } - # r.monitor(port = Ractor::Port.new) - # port.receive #=> :terminated and r is terminated with an exception "foo" + # r = Ractor.new{ raise "foo" } + # r.monitor(port = Ractor::Port.new) + # port.receive #=> :aborted and r is terminated by the RuntimeError "foo" # def monitor: [T < Symbol] (Port[T]) -> untyped # - # It is equivalent to default_port.send(msg) + # This is equivalent to Port#send to the ractor's #default_port. # def send: (untyped obj, ?move: boolish) -> Ractor @@ -529,7 +571,7 @@ class Ractor # rdoc-file=ractor.rb # - ractor.unmonitor(port) -> self # --> - # Unregister port from the monitoring ports. + # Unregisters the port from the monitoring ports for this ractor. # def unmonitor: (Port[untyped]) -> self @@ -537,9 +579,10 @@ class Ractor # rdoc-file=ractor.rb # - ractor.value -> obj # --> - # Waits for `ractor` to complete, using #join, and return its value or raise the - # exception which terminated the Ractor. The value will not be copied even if it - # is unshareable object. Therefore at most 1 Ractor can get a value. + # Waits for `ractor` to complete and returns its value or raises the exception + # which terminated the Ractor. The termination value will be moved to the + # calling Ractor. Therefore, at most 1 Ractor can receive another ractor's + # termination value. # # r = Ractor.new{ [1, 2] } # r.value #=> [1, 2] (unshareable object) @@ -576,36 +619,16 @@ class Ractor # # Raised when an attempt is made to send a message to a closed port, or to # retrieve a message from a closed and empty port. Ports may be closed - # explicitly with Ractor#close_outgoing/close_incoming and are closed implicitly - # when a Ractor terminates. - # - # r = Ractor.new { sleep(500) } - # r.close_outgoing - # r.take # Ractor::ClosedError - # - # ClosedError is a descendant of StopIteration, so the closing of the ractor - # will break the loops without propagating the error: + # explicitly with Ractor::Port#close and are closed implicitly when a Ractor + # terminates. # - # r = Ractor.new do - # loop do - # msg = receive # raises ClosedError and loop traps it - # puts "Received: #{msg}" - # end - # puts "loop exited" - # end - # - # 3.times{|i| r << i} - # r.close_incoming - # r.take - # puts "Continue successfully" + # port = Ractor::Port.new + # port.close + # port << "test" # Ractor::ClosedError + # port.receive # Ractor::ClosedError # - # This will print: - # - # Received: 0 - # Received: 1 - # Received: 2 - # loop exited - # Continue successfully + # ClosedError is a descendant of StopIteration, so the closing of a port will + # break out of loops without propagating the error. # class ClosedError < StopIteration end @@ -624,7 +647,7 @@ class Ractor # # Raised on an attempt to access an object which was moved in Ractor#send or - # Ractor.yield. + # Ractor::Port#send. # # r = Ractor.new { sleep } # @@ -638,7 +661,7 @@ class Ractor # # A special object which replaces any value that was moved to another ractor in - # Ractor#send or Ractor.yield. Any attempt to access the object results in + # Ractor#send or Ractor::Port#send. Any attempt to access the object results in # Ractor::MovedError. # # r = Ractor.new { receive } @@ -730,22 +753,10 @@ class Ractor # rdoc-file=ractor.rb # - port.close # --> - # Close the port. On the closed port, sending is not prohibited. Receiving is - # also not allowed if there is no sent messages arrived before closing. + # Closes the port. Sending to a closed port is prohibited. Receiving is also + # prohibited if there are no messages in its message queue. # - # port = Ractor::Port.new - # Ractor.new port do |port| - # port.send 1 # OK - # port.send 2 # OK - # port.close - # port.send 3 # raise Ractor::ClosedError - # end - # - # port.receive #=> 1 - # port.receive #=> 2 - # port.receive #=> raise Ractor::ClosedError - # - # Now, only a Ractor which creates the port is allowed to close ports. + # Only the Ractor which created the port is allowed to close it. # # port = Ractor::Port.new # Ractor.new port do |port| @@ -758,7 +769,7 @@ class Ractor # rdoc-file=ractor.rb # - port.closed? -> true/false # --> - # Return the port is closed or not. + # Returns whether or not the port is closed. # def closed?: () -> bool @@ -773,7 +784,8 @@ class Ractor # rdoc-file=ractor.rb # - port.receive -> msg # --> - # Receive a message to the port (which was sent there by Port#send). + # Receives a message from the port (which was sent there by Port#send). Only the + # ractor that created the port can receive messages this way. # # port = Ractor::Port.new # r = Ractor.new port do |port| @@ -783,9 +795,9 @@ class Ractor # v1 = port.receive # puts "Received: #{v1}" # r.join - # # Here will be printed: "Received: message1" + # # This will print: "Received: message1" # - # The method blocks if the message queue is empty. + # The method blocks the current Thread if the message queue is empty. # # port = Ractor::Port.new # r = Ractor.new port do |port| @@ -811,8 +823,8 @@ class Ractor # Still received only one # Received: message2 # - # If close_incoming was called on the ractor, the method raises - # Ractor::ClosedError if there are no more messages in the message queue: + # If the port is closed and there are no more messages in the message queue, the + # method raises Ractor::ClosedError. # # port = Ractor::Port.new # port.close @@ -824,28 +836,27 @@ class Ractor # rdoc-file=ractor.rb # - port.send(msg, move: false) -> self # --> - # Send a message to a port to be accepted by port.receive. + # Sends a message to the port to be accepted by port.receive. # # port = Ractor::Port.new - # r = Ractor.new do - # r.send 'message' + # r = Ractor.new(port) do |port| + # port.send 'message' # end # value = port.receive # puts "Received #{value}" # # Prints: "Received: message" # - # The method is non-blocking (will return immediately even if the ractor is not - # ready to receive anything): + # The method is non-blocking (it will return immediately even if the ractor that + # created the port is not ready to receive anything): # # port = Ractor::Port.new # r = Ractor.new(port) do |port| - # port.send 'test'} + # port.send 'test' # puts "Sent successfully" # # Prints: "Sent successfully" immediately # end # - # An attempt to send to a port which already closed its execution will raise - # Ractor::ClosedError. + # An attempt to send to a closed port will raise Ractor::ClosedError. # # r = Ractor.new {Ractor::Port.new} # r.join @@ -857,8 +868,8 @@ class Ractor # If the `obj` is unshareable, by default it will be copied into the receiving # ractor by deep cloning. # - # If the object is shareable, it only send a reference to the object without - # cloning. + # If the object is shareable, a reference to the object will be sent to the + # receiving ractor. # def send: (T obj, ?move: boolish) -> self @@ -876,14 +887,14 @@ class Ractor end # - # Raised on attempt to Ractor#take if there was an uncaught exception in the - # Ractor. Its `cause` will contain the original exception, and `ractor` is the - # original ractor it was raised in. + # Raised on Ractor#join or Ractor#value if there was an uncaught exception in + # the Ractor. Its `cause` will contain the original exception, and `ractor` is + # the original ractor it was raised in. # # r = Ractor.new { raise "Something weird happened" } # # begin - # r.take + # r.value # rescue => e # p e # => # # p e.ractor == r # => true @@ -892,7 +903,7 @@ class Ractor # class RemoteError < Ractor::Error # - # The Ractor an uncaught exception is raised in. + # The Ractor in which the uncaught exception was raised. # def ractor: () -> Ractor end diff --git a/core/rational.rbs b/core/rational.rbs index 891027ed1..0779f8ce9 100644 --- a/core/rational.rbs +++ b/core/rational.rbs @@ -155,20 +155,29 @@ class Rational < Numeric # - # Returns -1, 0, or +1 depending on whether `rational` is less than, equal to, - # or greater than `numeric`. + # Compares `self` and `other`. # - # `nil` is returned if the two values are incomparable. + # Returns: # - # Rational(2, 3) <=> Rational(2, 3) #=> 0 - # Rational(5) <=> 5 #=> 0 - # Rational(2, 3) <=> Rational(1, 3) #=> 1 - # Rational(1, 3) <=> 1 #=> -1 - # Rational(1, 3) <=> 0.3 #=> 1 + # * `-1`, if `self` is less than `other`. + # * `0`, if the two values are the same. + # * `1`, if `self` is greater than `other`. + # * `nil`, if the two values are incomparable. # - # Rational(1, 3) <=> "0.3" #=> nil + # Examples: + # + # Rational(2, 3) <=> Rational(4, 3) # => -1 + # Rational(2, 1) <=> Rational(2, 1) # => 0 + # Rational(2, 1) <=> 2 # => 0 + # Rational(2, 1) <=> 2.0 # => 0 + # Rational(2, 1) <=> Complex(2, 0) # => 0 + # Rational(4, 3) <=> Rational(2, 3) # => 1 + # Rational(4, 3) <=> :foo # => nil + # + # Class Rational includes module Comparable, each of whose methods uses + # Rational#<=> for comparison. # def <=>: (Integer | Rational) -> Integer | (untyped) -> Integer? diff --git a/core/set.rbs b/core/set.rbs index 2e6717cb7..33c163eff 100644 --- a/core/set.rbs +++ b/core/set.rbs @@ -299,7 +299,7 @@ class Set[unchecked out A] # rdoc-file=set.c # - add(obj) -> self # --> - # Adds the given object to the set and returns self. Use `merge` to add many + # Adds the given object to the set and returns self. Use Set#merge to add many # elements at once. # # Set[1, 2].add(3) #=> Set[1, 2, 3] @@ -309,7 +309,7 @@ class Set[unchecked out A] def add: (A) -> self # - # Adds the given object to the set and returns self. Use `merge` to add many + # Adds the given object to the set and returns self. Use Set#merge to add many # elements at once. # # Set[1, 2].add(3) #=> Set[1, 2, 3] diff --git a/core/signal.rbs b/core/signal.rbs index 8a6cbaace..f0a867390 100644 --- a/core/signal.rbs +++ b/core/signal.rbs @@ -65,26 +65,36 @@ module Signal # - # Specifies the handling of signals. The first parameter is a signal name (a - # string such as ``SIGALRM'', ``SIGUSR1'', and so on) or a signal number. The - # characters ``SIG'' may be omitted from the signal name. The command or block - # specifies code to be run when the signal is raised. If the command is the - # string ``IGNORE'' or ``SIG_IGN'', the signal will be ignored. If the command - # is ``DEFAULT'' or ``SIG_DFL'', the Ruby's default handler will be invoked. If - # the command is ``EXIT'', the script will be terminated by the signal. If the - # command is ``SYSTEM_DEFAULT'', the operating system's default handler will be - # invoked. Otherwise, the given command or block will be run. The special signal - # name ``EXIT'' or signal number zero will be invoked just prior to program - # termination. trap returns the previous handler for the given signal. + # Specifies the handling of signals. Returns the previous handler for the given + # signal. + # + # Argument `signal` is a signal name (a string or symbol such as `SIGALRM` or + # `SIGUSR1`) or an integer signal number. When `signal` is a string or symbol, + # the leading characters `SIG` may be omitted. + # + # Argument `command` or block provided specifies code to be run when the signal + # is raised. + # + # Argument `command` may also be a string or symbol with the following special + # values: + # + # * `IGNORE`, `SIG_IGN`: the signal will be ignored. + # * `DEFAULT`, `SIG_DFL`: Ruby's default handler will be invoked. + # * `EXIT`: the process will be terminated by the signal. + # * `SYSTEM_DEFAULT`: the operating system's default handler will be invoked. + # + # The special signal name `EXIT` or signal number zero will be invoked just + # prior to program termination: # # Signal.trap(0, proc { puts "Terminating: #{$$}" }) # Signal.trap("CLD") { puts "Child died" } # fork && Process.wait # - # *produces:* + # Outputs: + # # Terminating: 27461 # Child died # Terminating: 27460 diff --git a/core/string.rbs b/core/string.rbs index f9e49719d..869ef864e 100644 --- a/core/string.rbs +++ b/core/string.rbs @@ -1177,23 +1177,28 @@ class String # - # Compares `self` and `other_string`, returning: + # Compares `self` and `other`, evaluating their *contents*, not their *lengths*. # - # * -1 if `other_string` is larger. - # * 0 if the two are equal. - # * 1 if `other_string` is smaller. - # * `nil` if the two are incomparable. + # Returns: + # + # * `-1`, if `self` is smaller. + # * `0`, if the two are equal. + # * `1`, if `self` is larger. + # * `nil`, if the two are incomparable. # # Examples: # - # 'foo' <=> 'foo' # => 0 - # 'foo' <=> 'food' # => -1 - # 'food' <=> 'foo' # => 1 - # 'FOO' <=> 'foo' # => -1 - # 'foo' <=> 'FOO' # => 1 - # 'foo' <=> 1 # => nil + # 'a' <=> 'b' # => -1 + # 'a' <=> 'ab' # => -1 + # 'a' <=> 'a' # => 0 + # 'b' <=> 'a' # => 1 + # 'ab' <=> 'a' # => 1 + # 'a' <=> :a # => nil + # + # Class String includes module Comparable, each of whose methods uses String#<=> + # for comparison. # # Related: see [Comparing](rdoc-ref:String@Comparing). # @@ -1576,9 +1581,9 @@ class String # s['ll'] = 'foo' # => "foo" # s # => "hefooo" # - # s = 'тест' - # s['ес'] = 'foo' # => "foo" - # s # => "тfooт" + # s = 'Привет' + # s['ив'] = 'foo' # => "foo" + # s # => "Прfooет" # # s = 'こんにちは' # s['んにち'] = 'foo' # => "foo" @@ -1817,8 +1822,8 @@ class String # --> # Returns an array of the bytes in `self`: # - # 'hello'.bytes # => [104, 101, 108, 108, 111] - # 'тест'.bytes # => [209, 130, 208, 181, 209, 129, 209, 130] + # 'hello'.bytes # => [104, 101, 108, 108, 111] + # 'Привет'.bytes # => [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] # 'こんにちは'.bytes # # => [227, 129, 147, 227, 130, 147, 227, 129, 171, 227, 129, 161, 227, 129, 175] # @@ -1840,9 +1845,9 @@ class String # s = 'foo' # s.bytesize # => 3 # s.size # => 3 - # s = 'тест' - # s.bytesize # => 8 - # s.size # => 4 + # s = 'Привет' + # s.bytesize # => 12 + # s.size # => 6 # s = 'こんにちは' # s.bytesize # => 15 # s.size # => 5 @@ -2108,7 +2113,7 @@ class String # 'hello'.center(20, '-|') # => "-|-|-|-hello-|-|-|-|" # Some padding repeated. # 'hello'.center(10, 'abcdefg') # => "abhelloabc" # Some padding not used. # ' hello '.center(13) # => " hello " - # 'тест'.center(10) # => " тест " + # 'Привет'.center(10) # => " Привет " # 'こんにちは'.center(10) # => " こんにちは " # Multi-byte characters. # # If `size` is less than or equal to the size of `self`, returns an unpadded @@ -2129,7 +2134,7 @@ class String # Returns an array of the characters in `self`: # # 'hello'.chars # => ["h", "e", "l", "l", "o"] - # 'тест'.chars # => ["т", "е", "с", "т"] + # 'Привет'.chars # => ["П", "р", "и", "в", "е", "т"] # 'こんにちは'.chars # => ["こ", "ん", "に", "ち", "は"] # ''.chars # => [] # @@ -3928,8 +3933,8 @@ class String # `self`, not `self`. # # If `pattern` is a Regexp, performs the equivalent of `self.match(pattern)` - # (also setting [pattern-matching global - # variables](rdoc-ref:language/globals.md@Pattern+Matching)): + # (also setting [matched-data + # variables](rdoc-ref:language/globals.md@Matched+Data)): # # 'hello'.partition(/h/) # => ["", "h", "ello"] # 'hello'.partition(/l/) # => ["he", "l", "lo"] @@ -3942,8 +3947,8 @@ class String # # If `pattern` is not a Regexp, converts it to a string (if it is not already # one), then performs the equivalent of `self.index(pattern)` (and does *not* - # set [pattern-matching global - # variables](rdoc-ref:language/globals.md@Pattern+Matching)): + # set [matched-data global + # variables](rdoc-ref:language/globals.md@Matched+Data)): # # 'hello'.partition('h') # => ["", "h", "ello"] # 'hello'.partition('l') # => ["he", "l", "lo"] @@ -4133,8 +4138,8 @@ class String # `self`, not `self`. # # If `pattern` is a Regexp, searches for the last matching substring (also - # setting [pattern-matching global - # variables](rdoc-ref:language/globals.md@Pattern+Matching)): + # setting [matched-data global + # variables](rdoc-ref:language/globals.md@Matched+Data)): # # 'hello'.rpartition(/l/) # => ["hel", "l", "o"] # 'hello'.rpartition(/ll/) # => ["he", "ll", "o"] @@ -4147,8 +4152,7 @@ class String # # If `pattern` is not a Regexp, converts it to a string (if it is not already # one), then searches for the last matching substring (and does *not* set - # [pattern-matching global - # variables](rdoc-ref:language/globals.md@Pattern+Matching)): + # [matched-data global variables](rdoc-ref:language/globals.md@Matched+Data)): # # 'hello'.rpartition('l') # => ["hel", "l", "o"] # 'hello'.rpartition('ll') # => ["he", "ll", "o"] diff --git a/core/symbol.rbs b/core/symbol.rbs index 9e21ff95a..935ab4380 100644 --- a/core/symbol.rbs +++ b/core/symbol.rbs @@ -130,19 +130,25 @@ class Symbol # - # If `object` is a symbol, returns the equivalent of `symbol.to_s <=> - # object.to_s`: + # Compares `self` and `other`, using String#<=>. # - # :bar <=> :foo # => -1 - # :foo <=> :foo # => 0 - # :foo <=> :bar # => 1 + # Returns: # - # Otherwise, returns `nil`: + # * `self.to_s <=> other.to_s`, if `other` is a symbol. + # * `nil`, otherwise. # + # Examples: + # + # :bar <=> :foo # => -1 + # :foo <=> :foo # => 0 + # :foo <=> :bar # => 1 # :foo <=> 'bar' # => nil # + # Class Symbol includes module Comparable, each of whose methods uses Symbol#<=> + # for comparison. + # # Related: String#<=>. # def <=>: (Symbol object) -> (-1 | 0 | 1) diff --git a/core/thread.rbs b/core/thread.rbs index 641f85e7b..11d17a090 100644 --- a/core/thread.rbs +++ b/core/thread.rbs @@ -956,12 +956,11 @@ class Thread < Object # # Raises an exception from the given thread. The caller does not have to be - # `thr`. See Kernel#raise for more information. + # `thr`. See Kernel#raise for more information on arguments. # # Thread.abort_on_exception = true # a = Thread.new { sleep(200) } diff --git a/stdlib/cgi-escape/0/escape.rbs b/stdlib/cgi-escape/0/escape.rbs index 45baa4da1..7ef1d01a9 100644 --- a/stdlib/cgi-escape/0/escape.rbs +++ b/stdlib/cgi-escape/0/escape.rbs @@ -1,5 +1,15 @@ # -# :stopdoc +# Since Ruby 4.0, CGI is a small holder for various escaping methods, included +# from CGI::Escape +# +# require 'cgi/escape' +# +# CGI.escape("Ruby programming language") +# #=> "Ruby+programming+language" +# CGI.escapeURIComponent("Ruby programming language") +# #=> "Ruby%20programming%20language" +# +# See CGI::Escape module for methods list and their description. # class CGI include Escape @@ -7,7 +17,7 @@ class CGI extend Escape # - # Escape/unescape for CGI, HTML, URI. + # Web-related escape/unescape functionality. # module Escape # # URL-encode a string into application/x-www-form-urlencoded. Space characters - # (+" "+) are encoded with plus signs (+"+"+) + # (`" "`) are encoded with plus signs (`"+"`) # url_encoded_string = CGI.escape("'Stop!' said Fred") # # => "%27Stop%21%27+said+Fred" # @@ -45,7 +55,7 @@ class CGI # rdoc-file=lib/cgi/escape.rb # - escapeHTML(string) # --> - # Escape special characters in HTML, namely '&"<> + # Escape special characters in HTML, namely `'&\"<>` # CGI.escapeHTML('Usage: foo "bar" ') # # => "Usage: foo "bar" <baz>" # @@ -55,20 +65,24 @@ class CGI # rdoc-file=lib/cgi/escape.rb # - escapeURIComponent(string) # --> - # URL-encode a string following RFC 3986 Space characters (+" "+) are encoded - # with (+"%20"+) + # URL-encode a string following RFC 3986 Space characters (`" "`) are encoded + # with (`"%20"`) # url_encoded_string = CGI.escapeURIComponent("'Stop!' said Fred") # # => "%27Stop%21%27%20said%20Fred" # def escapeURIComponent: (string) -> String - # - # Synonym for CGI.escapeElement(str) + # # alias escape_element escapeElement - # - # Synonym for CGI.escapeHTML(str) + # # alias escape_html escapeHTML @@ -101,7 +115,7 @@ class CGI # rdoc-file=lib/cgi/escape.rb # - unescapeElement(string, *elements) # --> - # Undo escaping such as that done by CGI.escapeElement() + # Undo escaping such as that done by CGI.escapeElement # # print CGI.unescapeElement( # CGI.escapeHTML('
'), "A", "IMG") @@ -133,13 +147,17 @@ class CGI # def unescapeURIComponent: (string) -> String - # - # Synonym for CGI.unescapeElement(str) + # # alias unescape_element unescapeElement - # - # Synonym for CGI.unescapeHTML(str) + # # alias unescape_html unescapeHTML diff --git a/stdlib/cgi/0/core.rbs b/stdlib/cgi/0/core.rbs index 4c563f0de..59484f500 100644 --- a/stdlib/cgi/0/core.rbs +++ b/stdlib/cgi/0/core.rbs @@ -1,5 +1,15 @@ # -# :stopdoc +# Since Ruby 4.0, CGI is a small holder for various escaping methods, included +# from CGI::Escape +# +# require 'cgi/escape' +# +# CGI.escape("Ruby programming language") +# #=> "Ruby+programming+language" +# CGI.escapeURIComponent("Ruby programming language") +# #=> "Ruby%20programming%20language" +# +# See CGI::Escape module for methods list and their description. # class CGI include CGI::Util