diff --git a/.github/workflows/comments.yml b/.github/workflows/comments.yml index 6fea1e44d..d24d9dcd7 100644 --- a/.github/workflows/comments.yml +++ b/.github/workflows/comments.yml @@ -13,7 +13,7 @@ jobs: container: image: rubylang/ruby:3.2-dev-focal env: - RUBY_COMMIT: v3_3_0_rc1 + RUBY_COMMIT: v3_3_0 steps: - uses: actions/checkout@v4 - name: Install dependencies diff --git a/core/complex.rbs b/core/complex.rbs index a7333e5c7..b251a051b 100644 --- a/core/complex.rbs +++ b/core/complex.rbs @@ -36,6 +36,10 @@ # *argument* parts; see [Complex polar # plane](https://en.wikipedia.org/wiki/Complex_number#Polar_complex_plane). # +# In this class, the argument part in expressed +# [radians](https://en.wikipedia.org/wiki/Radian) (not +# [degrees](https://en.wikipedia.org/wiki/Degree_(angle))). +# # You can create a Complex object from polar coordinates with: # # * Method Complex.polar. @@ -62,7 +66,7 @@ class Complex < Numeric # --> # Returns a new Complex object formed from the arguments, each of which must be # an instance of Numeric, or an instance of one of its subclasses: Complex, - # Float, Integer, Rational; see [Polar + # Float, Integer, Rational. Argument `arg` is given in radians; see [Polar # Coordinates](rdoc-ref:Complex@Polar+Coordinates): # # Complex.polar(3) # => (3+0i) @@ -109,40 +113,40 @@ class Complex < Numeric # - # Performs multiplication. + # Returns the product of `self` and `numeric`: # - # Complex(2, 3) * Complex(2, 3) #=> (-5+12i) - # Complex(900) * Complex(1) #=> (900+0i) - # Complex(-2, 9) * Complex(-9, 2) #=> (0-85i) - # Complex(9, 8) * 4 #=> (36+32i) - # Complex(20, 9) * 9.8 #=> (196.0+88.2i) + # Complex(2, 3) * Complex(2, 3) # => (-5+12i) + # Complex(900) * Complex(1) # => (900+0i) + # Complex(-2, 9) * Complex(-9, 2) # => (0-85i) + # Complex(9, 8) * 4 # => (36+32i) + # Complex(20, 9) * 9.8 # => (196.0+88.2i) # def *: (Numeric) -> Complex # - # Performs exponentiation. + # Returns `self` raised to power `numeric`: # - # Complex('i') ** 2 #=> (-1+0i) - # Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i) + # Complex('i') ** 2 # => (-1+0i) + # Complex(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i) # def **: (Numeric) -> Complex # - # Performs addition. + # Returns the sum of `self` and `numeric`: # - # Complex(2, 3) + Complex(2, 3) #=> (4+6i) - # Complex(900) + Complex(1) #=> (901+0i) - # Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i) - # Complex(9, 8) + 4 #=> (13+8i) - # Complex(20, 9) + 9.8 #=> (29.8+9i) + # Complex(2, 3) + Complex(2, 3) # => (4+6i) + # Complex(900) + Complex(1) # => (901+0i) + # Complex(-2, 9) + Complex(-9, 2) # => (-11+11i) + # Complex(9, 8) + 4 # => (13+8i) + # Complex(20, 9) + 9.8 # => (29.8+9i) # def +: (Numeric) -> Complex @@ -150,40 +154,40 @@ class Complex < Numeric # - # Performs subtraction. + # Returns the difference of `self` and `numeric`: # - # Complex(2, 3) - Complex(2, 3) #=> (0+0i) - # Complex(900) - Complex(1) #=> (899+0i) - # Complex(-2, 9) - Complex(-9, 2) #=> (7+7i) - # Complex(9, 8) - 4 #=> (5+8i) - # Complex(20, 9) - 9.8 #=> (10.2+9i) + # Complex(2, 3) - Complex(2, 3) # => (0+0i) + # Complex(900) - Complex(1) # => (899+0i) + # Complex(-2, 9) - Complex(-9, 2) # => (7+7i) + # Complex(9, 8) - 4 # => (5+8i) + # Complex(20, 9) - 9.8 # => (10.2+9i) # def -: (Numeric) -> Complex # - # Returns negation of the value. + # Returns the negation of `self`, which is the negation of each of its parts: # - # -Complex(1, 2) #=> (-1-2i) + # -Complex(1, 2) # => (-1-2i) + # -Complex(-1, -2) # => (1+2i) # def -@: () -> Complex # - # Performs division. + # Returns the quotient of `self` and `numeric`: # - # Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i) - # Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i) - # Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i) - # Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i) - # Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i) + # Complex(2, 3) / Complex(2, 3) # => ((1/1)+(0/1)*i) + # Complex(900) / Complex(1) # => ((900/1)+(0/1)*i) + # Complex(-2, 9) / Complex(-9, 2) # => ((36/85)-(77/85)*i) + # Complex(9, 8) / 4 # => ((9/4)+(2/1)*i) + # Complex(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def /: (Numeric) -> Complex @@ -193,31 +197,38 @@ class Complex < Numeric # - # If `cmp`'s imaginary part is zero, and `object` is also a real number (or a - # Complex number where the imaginary part is zero), compare the real part of - # `cmp` to object. Otherwise, return nil. + # Returns: + # + # * `self.real <=> object.real` if both of the following are true: + # + # * `self.imag == 0`. + # * `object.imag == 0`. # Always true if object is numeric but not + # complex. + # + # + # * `nil` otherwise. + # # - # Complex(2, 3) <=> Complex(2, 3) #=> nil - # Complex(2, 3) <=> 1 #=> nil - # Complex(2) <=> 1 #=> 1 - # Complex(2) <=> 2 #=> 0 - # Complex(2) <=> 3 #=> -1 + # Examples: + # + # Complex(2) <=> 3 # => -1 + # Complex(2) <=> 2 # => 0 + # Complex(2) <=> 1 # => 1 + # Complex(2, 1) <=> 1 # => nil # self.imag not zero. + # Complex(1) <=> Complex(1, 1) # => nil # object.imag not zero. + # Complex(1) <=> 'Foo' # => nil # object.imag not defined. # def <=>: (untyped) -> Integer? # - # Returns true if cmp equals object numerically. + # Returns `true` if `self.real == object.real` and `self.imag == object.imag`: # - # Complex(2, 3) == Complex(2, 3) #=> true - # Complex(5) == 5 #=> true - # Complex(0) == 0.0 #=> true - # Complex('1/3') == 0.33 #=> false - # Complex('1/2') == '1/2' #=> false + # Complex(2, 3) == Complex(2.0, 3.0) # => true # def ==: (untyped) -> bool @@ -227,43 +238,66 @@ class Complex < Numeric # - # Returns the absolute part of its polar form. + # Returns the absolute value (magnitude) for `self`; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): + # + # Complex.polar(-1, 0).abs # => 1.0 + # + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: # - # Complex(-1).abs #=> 1 - # Complex(3.0, -4.0).abs #=> 5.0 + # Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2. # def abs: () -> Numeric # - # Returns square of the absolute value. + # Returns square of the absolute value (magnitude) for `self`; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): # - # Complex(-1).abs2 #=> 1 - # Complex(3.0, -4.0).abs2 #=> 25.0 + # Complex.polar(2, 2).abs2 # => 4.0 + # + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.rectangular(1.0/3, 1.0/3).abs2 # => 0.2222222222222222 # def abs2: () -> Numeric # - # Returns the angle part of its polar form. + # Returns the argument (angle) for `self` in radians; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): + # + # Complex.polar(3, Math::PI/2).arg # => 1.57079632679489660 # - # Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966 + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.polar(1, 1.0/3).arg # => 0.33333333333333326 # def angle: () -> Float # - # Returns the angle part of its polar form. + # Returns the argument (angle) for `self` in radians; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): + # + # Complex.polar(3, Math::PI/2).arg # => 1.57079632679489660 + # + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: # - # Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966 + # Complex.polar(1, 1.0/3).arg # => 0.33333333333333326 # alias arg angle @@ -272,30 +306,35 @@ class Complex < Numeric def coerce: (Numeric) -> [ Complex, Complex ] # - # Returns the complex conjugate. + # Returns the conjugate of `self`, `Complex.rect(self.imag, self.real)`: # - # Complex(1, 2).conjugate #=> (1-2i) + # Complex.rect(1, 2).conj # => (1-2i) # def conj: () -> Complex # - # Returns the complex conjugate. + # Returns the conjugate of `self`, `Complex.rect(self.imag, self.real)`: # - # Complex(1, 2).conjugate #=> (1-2i) + # Complex.rect(1, 2).conj # => (1-2i) # def conjugate: () -> Complex # - # Returns the denominator (lcm of both denominator - real and imag). + # Returns the denominator of `self`, which is the [least common + # multiple](https://en.wikipedia.org/wiki/Least_common_multiple) of + # `self.real.denominator` and `self.imag.denominator`: # - # See numerator. + # Complex.rect(Rational(1, 2), Rational(2, 3)).denominator # => 6 + # + # Note that `n.denominator` of a non-rational numeric is `1`. + # + # Related: Complex#numerator. # def denominator: () -> Integer @@ -309,20 +348,25 @@ class Complex < Numeric # - # Performs division as each part is a float, never returns a float. + # Returns `Complex(self.real/numeric, self.imag/numeric)`: # - # Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i) + # Complex(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i) # def fdiv: (Numeric) -> Complex # - # Returns `true` if `cmp`'s real and imaginary parts are both finite numbers, - # otherwise returns `false`. + # Returns `true` if both `self.real.finite?` and `self.imag.finite?` are true, + # `false` otherwise: + # + # Complex(1, 1).finite? # => true + # Complex(Float::INFINITY, 0).finite? # => false + # + # Related: Numeric#finite?, Float#finite?. # def finite?: () -> bool @@ -330,68 +374,91 @@ class Complex < Numeric # + # Returns the integer hash value for `self`. + # + # Two Complex objects created from the same values will have the same hash value + # (and will compare using #eql?): + # + # Complex(1, 2).hash == Complex(1, 2).hash # => true # def hash: () -> Integer def i: () -> bot # - # Returns the imaginary part. + # Returns the imaginary value for `self`: # # Complex(7).imaginary #=> 0 # Complex(9, -4).imaginary #=> -4 # + # If `self` was created with [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2. + # def imag: () -> Numeric # - # Returns the imaginary part. + # Returns the imaginary value for `self`: # # Complex(7).imaginary #=> 0 # Complex(9, -4).imaginary #=> -4 # + # If `self` was created with [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2. + # def imaginary: () -> Numeric # - # Returns `1` if `cmp`'s real or imaginary part is an infinite number, otherwise - # returns `nil`. + # Returns `1` if either `self.real.infinite?` or `self.imag.infinite?` is true, + # `nil` otherwise: # - # For example: + # Complex(Float::INFINITY, 0).infinite? # => 1 + # Complex(1, 1).infinite? # => nil # - # (1+1i).infinite? #=> nil - # (Float::INFINITY + 1i).infinite? #=> 1 + # Related: Numeric#infinite?, Float#infinite?. # def infinite?: () -> Integer? # - # Returns the value as a string for inspection. + # Returns a string representation of `self`: # - # Complex(2).inspect #=> "(2+0i)" - # Complex('-8/6').inspect #=> "((-4/3)+0i)" - # Complex('1/2i').inspect #=> "(0+(1/2)*i)" - # Complex(0, Float::INFINITY).inspect #=> "(0+Infinity*i)" - # Complex(Float::NAN, Float::NAN).inspect #=> "(NaN+NaN*i)" + # Complex(2).inspect # => "(2+0i)" + # Complex('-8/6').inspect # => "((-4/3)+0i)" + # Complex('1/2i').inspect # => "(0+(1/2)*i)" + # Complex(0, Float::INFINITY).inspect # => "(0+Infinity*i)" + # Complex(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)" # def inspect: () -> String def integer?: () -> bool # - # Returns the absolute part of its polar form. + # Returns the absolute value (magnitude) for `self`; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): + # + # Complex.polar(-1, 0).abs # => 1.0 # - # Complex(-1).abs #=> 1 - # Complex(3.0, -4.0).abs #=> 5.0 + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2. # alias magnitude abs @@ -403,39 +470,54 @@ class Complex < Numeric # - # Returns the numerator. + # Returns the Complex object created from the numerators of the real and + # imaginary parts of `self`, after converting each part to the [lowest common + # denominator](https://en.wikipedia.org/wiki/Lowest_common_denominator) of the + # two: # - # 1 2 3+4i <- numerator - # - + -i -> ---- - # 2 3 6 <- denominator + # c = Complex(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i) + # c.numerator # => (8+9i) # - # c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i) - # n = c.numerator #=> (3+4i) - # d = c.denominator #=> 6 - # n / d #=> ((1/2)+(2/3)*i) - # Complex(Rational(n.real, d), Rational(n.imag, d)) - # #=> ((1/2)+(2/3)*i) + # In this example, the lowest common denominator of the two parts is 12; the two + # converted parts may be thought of as Rational(8, 12) and Rational(9, 12), + # whose numerators, respectively, are 8 and 9; so the returned value of + # `c.numerator` is `Complex(8, 9)`. # - # See denominator. + # Related: Complex#denominator. # def numerator: () -> Complex # - # Returns the angle part of its polar form. + # Returns the argument (angle) for `self` in radians; see [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates): + # + # Complex.polar(3, Math::PI/2).arg # => 1.57079632679489660 + # + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: # - # Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966 + # Complex.polar(1, 1.0/3).arg # => 0.33333333333333326 # alias phase angle # - # Returns an array; [cmp.abs, cmp.arg]. + # Returns the array `[self.abs, self.arg]`: # - # Complex(1, 2).polar #=> [2.23606797749979, 1.1071487177940904] + # Complex.polar(1, 2).polar # => [1.0, 2.0] + # + # See [Polar Coordinates](rdoc-ref:Complex@Polar+Coordinates). + # + # If `self` was created with [rectangular + # coordinates](rdoc-ref:Complex@Rectangular+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.rect(1, 1).polar # => [1.4142135623730951, 0.7853981633974483] # def polar: () -> [ Numeric, Float ] @@ -443,51 +525,73 @@ class Complex < Numeric # - # Performs division. + # Returns the quotient of `self` and `numeric`: # - # Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i) - # Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i) - # Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i) - # Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i) - # Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i) + # Complex(2, 3) / Complex(2, 3) # => ((1/1)+(0/1)*i) + # Complex(900) / Complex(1) # => ((900/1)+(0/1)*i) + # Complex(-2, 9) / Complex(-9, 2) # => ((36/85)-(77/85)*i) + # Complex(9, 8) / 4 # => ((9/4)+(2/1)*i) + # Complex(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def quo: (Numeric) -> Complex # - # Returns the value as a rational if possible (the imaginary part should be - # exactly zero). + # Returns a Rational object whose value is exactly or approximately equivalent + # to that of `self.real`. + # + # With no argument `epsilon` given, returns a Rational object whose value is + # exactly equal to that of `self.real.rationalize`: + # + # Complex(1, 0).rationalize # => (1/1) + # Complex(1, Rational(0, 1)).rationalize # => (1/1) + # Complex(3.14159, 0).rationalize # => (314159/100000) # - # Complex(1.0/3, 0).rationalize #=> (1/3) - # Complex(1, 0.0).rationalize # RangeError - # Complex(1, 2).rationalize # RangeError + # With argument `epsilon` given, returns a Rational object whose value is + # exactly or approximately equal to that of `self.real` to the given precision: # - # See to_r. + # Complex(3.14159, 0).rationalize(0.1) # => (16/5) + # Complex(3.14159, 0).rationalize(0.01) # => (22/7) + # Complex(3.14159, 0).rationalize(0.001) # => (201/64) + # Complex(3.14159, 0).rationalize(0.0001) # => (333/106) + # Complex(3.14159, 0).rationalize(0.00001) # => (355/113) + # Complex(3.14159, 0).rationalize(0.000001) # => (7433/2366) + # Complex(3.14159, 0).rationalize(0.0000001) # => (9208/2931) + # Complex(3.14159, 0).rationalize(0.00000001) # => (47460/15107) + # Complex(3.14159, 0).rationalize(0.000000001) # => (76149/24239) + # Complex(3.14159, 0).rationalize(0.0000000001) # => (314159/100000) + # Complex(3.14159, 0).rationalize(0.0) # => (3537115888337719/1125899906842624) + # + # Related: Complex#to_r. # def rationalize: (?Numeric eps) -> Rational # - # Returns the real part. + # Returns the real value for `self`: # # Complex(7).real #=> 7 # Complex(9, -4).real #=> 9 # + # If `self` was created with [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is + # computed, and may be inexact: + # + # Complex.polar(1, Math::PI/4).real # => 0.7071067811865476 # Square root of 2. + # def real: () -> Numeric # - # Returns false, even if the complex number has no imaginary part. + # Returns `false`; for compatibility with Numeric#real?. # def real?: () -> false @@ -507,12 +611,21 @@ class Complex < Numeric # - # Returns an array; [cmp.real, cmp.imag]. + # Returns the array `[self.real, self.imag]`: + # + # Complex.rect(1, 2).rect # => [1, 2] + # + # See [Rectangular Coordinates](rdoc-ref:Complex@Rectangular+Coordinates). + # + # If `self` was created with [polar + # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is + # computed, and may be inexact: # - # Complex(1, 2).rectangular #=> [1, 2] + # Complex.polar(1.0, 1.0).rect # => [0.5403023058681398, 0.8414709848078965] + # + # Complex#rectangular is an alias for Complex#rect. # alias rectangular rect @@ -524,38 +637,37 @@ class Complex < Numeric # - # Returns self. - # - # Complex(2).to_c #=> (2+0i) - # Complex(-8, 6).to_c #=> (-8+6i) + # Returns `self`. # def to_c: () -> Complex # - # Returns the value as a float if possible (the imaginary part should be exactly - # zero). + # Returns the value of `self.real` as a Float, if possible: + # + # Complex(1, 0).to_f # => 1.0 + # Complex(1, Rational(0, 1)).to_f # => 1.0 # - # Complex(1, 0).to_f #=> 1.0 - # Complex(1, 0.0).to_f # RangeError - # Complex(1, 2).to_f # RangeError + # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or + # `Rational(0, *n*)`). # def to_f: () -> Float # - # Returns the value as an integer if possible (the imaginary part should be - # exactly zero). + # Returns the value of `self.real` as an Integer, if possible: # - # Complex(1, 0).to_i #=> 1 - # Complex(1, 0.0).to_i # RangeError - # Complex(1, 2).to_i # RangeError + # Complex(1, 0).to_i # => 1 + # Complex(1, Rational(0, 1)).to_i # => 1 + # + # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or + # `Rational(0, *n*)`). # def to_i: () -> Integer @@ -563,30 +675,31 @@ class Complex < Numeric # - # Returns the value as a rational if possible (the imaginary part should be - # exactly zero). + # Returns the value of `self.real` as a Rational, if possible: + # + # Complex(1, 0).to_r # => (1/1) + # Complex(1, Rational(0, 1)).to_r # => (1/1) # - # Complex(1, 0).to_r #=> (1/1) - # Complex(1, 0.0).to_r # RangeError - # Complex(1, 2).to_r # RangeError + # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or + # `Rational(0, *n*)`). # - # See rationalize. + # Related: Complex#rationalize. # def to_r: () -> Rational # - # Returns the value as a string. + # Returns a string representation of `self`: # - # Complex(2).to_s #=> "2+0i" - # Complex('-8/6').to_s #=> "-4/3+0i" - # Complex('1/2i').to_s #=> "0+1/2i" - # Complex(0, Float::INFINITY).to_s #=> "0+Infinity*i" - # Complex(Float::NAN, Float::NAN).to_s #=> "NaN+NaN*i" + # Complex(2).to_s # => "2+0i" + # Complex('-8/6').to_s # => "-4/3+0i" + # Complex('1/2i').to_s # => "0+1/2i" + # Complex(0, Float::INFINITY).to_s # => "0+Infinity*i" + # Complex(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i" # def to_s: () -> String diff --git a/core/dir.rbs b/core/dir.rbs index 446f19688..16c16ff0b 100644 --- a/core/dir.rbs +++ b/core/dir.rbs @@ -221,7 +221,7 @@ class Dir # # * Calls the block with the argument. # * Changes to the given directory. - # * Executes the block + # * Executes the block (yielding the new path). # * Restores the previous working directory. # * Returns the block's return value. # @@ -384,16 +384,14 @@ class Dir # Dir.pwd # => "/var/spool/mail" # dir = Dir.new('/usr') # fd = dir.fileno - # Dir.fchdir(fd) do - # Dir.pwd # => "/usr" - # end - # Dir.pwd # => "/var/spool/mail" + # Dir.fchdir(fd) + # Dir.pwd # => "/usr" # # With a block, temporarily changes the working directory: # # * Calls the block with the argument. # * Changes to the given directory. - # * Executes the block + # * Executes the block (yields no args). # * Restores the previous working directory. # * Returns the block's return value. # @@ -402,7 +400,9 @@ class Dir # # Dir.chdir('/var/spool/mail') # Dir.pwd # => "/var/spool/mail" - # Dir.chdir('/tmp') do + # dir = Dir.new('/tmp') + # fd = dir.fileno + # Dir.fchdir(fd) do # Dir.pwd # => "/tmp" # end # Dir.pwd # => "/var/spool/mail" @@ -763,15 +763,28 @@ class Dir # - # Changes the current working directory to the path of `self`: + # Changes the current working directory to `self`: # # Dir.pwd # => "/" # dir = Dir.new('example') # dir.chdir # Dir.pwd # => "/example" # + # With a block, temporarily changes the working directory: + # + # * Calls the block. + # * Changes to the given directory. + # * Executes the block (yields no args). + # * Restores the previous working directory. + # * Returns the block's return value. + # + # + # Uses Dir.fchdir if available, and Dir.chdir if not, see those methods for + # caveats. + # def chdir: () -> Integer | [T] { () -> T } -> T diff --git a/core/errors.rbs b/core/errors.rbs index 77ec797d4..6c1329cca 100644 --- a/core/errors.rbs +++ b/core/errors.rbs @@ -188,10 +188,6 @@ end # # LoadError: no such file to load -- this/file/does/not/exist # -# -# for RubyGems without Bundler environment. If loading library is not part of -# the default gems and the bundled gems, warn it. -# class LoadError < ScriptError # # the path failed to load @@ -348,7 +344,7 @@ end # # *raises the exception:* # -# NoMethodError: undefined method `to_ary' for "hello":String +# NoMethodError: undefined method `to_ary' for an instance of String # class NoMethodError[T] < NameError[T] # - # Locks or unlocks a file according to *locking_constant* (a logical *or* of the - # values in the table below). Returns `false` if File::LOCK_NB is specified and - # the operation would otherwise have blocked. Not available on all platforms. - # - # Locking constants (in class File): - # - # LOCK_EX | Exclusive lock. Only one process may hold an - # | exclusive lock for a given file at a time. - # ----------+------------------------------------------------ - # LOCK_NB | Don't block when locking. May be combined - # | with other lock options using logical or. - # ----------+------------------------------------------------ - # LOCK_SH | Shared lock. Multiple processes may each hold a - # | shared lock for a given file at the same time. - # ----------+------------------------------------------------ - # LOCK_UN | Unlock. - # - # Example: - # - # # update a counter using write lock - # # don't use "w" because it truncates the file before lock. - # File.open("counter", File::RDWR|File::CREAT, 0644) {|f| - # f.flock(File::LOCK_EX) - # value = f.read.to_i + 1 - # f.rewind - # f.write("#{value}\n") - # f.flush - # f.truncate(f.pos) - # } - # - # # read the counter using read lock - # File.open("counter", "r") {|f| - # f.flock(File::LOCK_SH) - # p f.read - # } + # - flock(locking_constant) -> 0 or false + # --> + # Locks or unlocks a file according to the given `locking_constant`, + # a bitwise OR of the values in the table below. + # Not available on all platforms. + # Returns `false` if `File::LOCK_NB` is specified and the operation would have + # blocked; + # otherwise returns `0`. + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + # + #
Locking Constants
ConstantLockEffect
File::LOCK_EXExclusiveOnly one process may hold an exclusive lock for self at a time.
File::LOCK_NBNon-blocking + # No blocking; may be combined with other File::LOCK_SH or File::LOCK_EX + # using the bitwise OR operator |. + #
File::LOCK_SHSharedMultiple processes may each hold a shared lock for self at the same time.
File::LOCK_UNUnlockRemove an existing lock held by this process.
+ # # Update a counter using an exclusive lock. + # # Don't use File::WRONLY because it truncates the file. + # File.open('counter', File::RDWR | File::CREAT, 0644) do |f| + # f.flock(File::LOCK_EX) + # value = f.read.to_i + 1 + # f.rewind + # f.write("#{value}\n") + # f.flush + # f.truncate(f.pos) + # end + # + # # Read the counter using a shared lock. + # File.open('counter', 'r') do |f| + # f.flock(File::LOCK_SH) + # f.read + # end # def flock: (int locking_constant) -> (0 | false) @@ -2292,64 +2313,158 @@ File::Separator: String module File::Constants end +# +# [File::APPEND](rdoc-ref:File::Constants@File-3A-3AAPPEND) +# File::Constants::APPEND: Integer +# +# [File::BINARY](rdoc-ref:File::Constants@File-3A-3ABINARY) +# File::Constants::BINARY: Integer +# +# [File::CREAT](rdoc-ref:File::Constants@File-3A-3ACREAT) +# File::Constants::CREAT: Integer +# +# [File::DIRECT](rdoc-ref:File::Constants@File-3A-3ADIRECT) +# File::Constants::DIRECT: Integer +# +# [File::DSYNC](rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+an +# d+File-3A-3ADSYNC) +# File::Constants::DSYNC: Integer +# +# [File::EXCL](rdoc-ref:File::Constants@File-3A-3AEXCL) +# File::Constants::EXCL: Integer +# +# [File::FNM_CASEFOLD](rdoc-ref:File::Constants@File-3A-3AFNM_CASEFOLD) +# File::Constants::FNM_CASEFOLD: Integer +# +# [File::FNM_DOTMATCH](rdoc-ref:File::Constants@File-3A-3AFNM_DOTMATCH) +# File::Constants::FNM_DOTMATCH: Integer +# +# [File::FNM_EXTGLOB](rdoc-ref:File::Constants@File-3A-3AFNM_EXTGLOB) +# File::Constants::FNM_EXTGLOB: Integer +# +# [File::FNM_NOESCAPE](rdoc-ref:File::Constants@File-3A-3AFNM_NOESCAPE) +# File::Constants::FNM_NOESCAPE: Integer +# +# [File::FNM_PATHNAME](rdoc-ref:File::Constants@File-3A-3AFNM_PATHNAME) +# File::Constants::FNM_PATHNAME: Integer +# +# [File::FNM_SHORTNAME](rdoc-ref:File::Constants@File-3A-3AFNM_SHORTNAME) +# File::Constants::FNM_SHORTNAME: Integer +# +# [File::FNM_SYSCASE](rdoc-ref:File::Constants@File-3A-3AFNM_SYSCASE) +# File::Constants::FNM_SYSCASE: Integer +# +# [File::LOCK_EX](rdoc-ref:File::Constants@File-3A-3ALOCK_EX) +# File::Constants::LOCK_EX: Integer +# +# [File::LOCK_NB](rdoc-ref:File::Constants@File-3A-3ALOCK_NB) +# File::Constants::LOCK_NB: Integer +# +# [File::LOCK_SH](rdoc-ref:File::Constants@File-3A-3ALOCK_SH) +# File::Constants::LOCK_SH: Integer +# +# [File::LOCK_UN](rdoc-ref:File::Constants@File-3A-3ALOCK_UN) +# File::Constants::LOCK_UN: Integer +# +# [File::NOATIME](rdoc-ref:File::Constants@File-3A-3ANOATIME) +# File::Constants::NOATIME: Integer +# +# [File::NOCTTY](rdoc-ref:File::Constants@File-3A-3ANOCTTY) +# File::Constants::NOCTTY: Integer +# +# [File::NOFOLLOW](rdoc-ref:File::Constants@File-3A-3ANOFOLLOW) +# File::Constants::NOFOLLOW: Integer +# +# [File::NONBLOCK](rdoc-ref:File::Constants@File-3A-3ANONBLOCK) +# File::Constants::NONBLOCK: Integer +# +# [File::NULL](rdoc-ref:File::Constants@File-3A-3ANULL) +# File::Constants::NULL: String +# +# [File::RDONLY](rdoc-ref:File::Constants@File-3A-3ARDONLY) +# File::Constants::RDONLY: Integer +# +# [File::RDWR](rdoc-ref:File::Constants@File-3A-3ARDWR) +# File::Constants::RDWR: Integer +# +# [File::RSYNC](rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+an +# d+File-3A-3ADSYNC) +# File::Constants::RSYNC: Integer +# +# [File::SHARE_DELETE](rdoc-ref:File::Constants@File-3A-3ASHARE_DELETE+-28Window +# s+Only-29) +# File::Constants::SHARE_DELETE: Integer +# +# [File::SYNC](rdoc-ref:File::Constants@File-3A-3ASYNC-2C+File-3A-3ARSYNC-2C+and +# +File-3A-3ADSYNC) +# File::Constants::SYNC: Integer +# +# [File::TMPFILE](rdoc-ref:File::Constants@File-3A-3ATMPFILE) +# File::Constants::TMPFILE: Integer +# +# [File::TRUNC](rdoc-ref:File::Constants@File-3A-3ATRUNC) +# File::Constants::TRUNC: Integer +# +# [File::WRONLY](rdoc-ref:File::Constants@File-3A-3AWRONLY) +# File::Constants::WRONLY: Integer # diff --git a/core/float.rbs b/core/float.rbs index 4bea96531..7ea0ec2bd 100644 --- a/core/float.rbs +++ b/core/float.rbs @@ -337,17 +337,15 @@ class Float < Numeric def abs2: () -> Float # - # Returns 0 if the value is positive, pi otherwise. + # Returns 0 if `self` is positive, Math::PI otherwise. # def angle: () -> (Integer | Float) # - # Returns 0 if the value is positive, pi otherwise. + # Returns 0 if `self` is positive, Math::PI otherwise. # alias arg angle @@ -708,7 +706,7 @@ class Float < Numeric def numerator: () -> Integer # - # Returns 0 if the value is positive, pi otherwise. + # Returns 0 if `self` is positive, Math::PI otherwise. # alias phase angle diff --git a/core/gc.rbs b/core/gc.rbs index 89ebd296e..457fd0b46 100644 --- a/core/gc.rbs +++ b/core/gc.rbs @@ -259,6 +259,7 @@ module GC # rdoc-file=gc.rb # - garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true) # --> + # Alias of GC.start # def garbage_collect: (?immediate_sweep: boolish immediate_sweep, ?immediate_mark: boolish immediate_mark, ?full_mark: boolish full_mark) -> nil end diff --git a/core/io.rbs b/core/io.rbs index aed70ec81..e533c0672 100644 --- a/core/io.rbs +++ b/core/io.rbs @@ -3378,10 +3378,19 @@ IO::TRUNC: Integer IO::WRONLY: Integer +# +# Readable event mask for IO#wait. +# IO::READABLE: Integer +# +# Writable event mask for IO#wait. +# IO::WRITABLE: Integer +# +# Priority event mask for IO#wait. +# IO::PRIORITY: Integer # diff --git a/core/io/buffer.rbs b/core/io/buffer.rbs index b068bc97b..8acb2c763 100644 --- a/core/io/buffer.rbs +++ b/core/io/buffer.rbs @@ -1,26 +1,29 @@ %a{annotate:rdoc:skip} class IO # - # IO::Buffer is a low-level efficient buffer for input/output. There are three - # ways of using buffer: + # IO::Buffer is a efficient zero-copy buffer for input/output. There are typical + # use cases: # # * Create an empty buffer with ::new, fill it with buffer using #copy or - # #set_value, #set_string, get buffer with #get_string; + # #set_value, #set_string, get buffer with #get_string or write it directly + # to some file with #write. # * Create a buffer mapped to some string with ::for, then it could be used # both for reading with #get_string or #get_value, and writing (writing will - # change the source string, too); + # change the source string, too). # * Create a buffer mapped to some file with ::map, then it could be used for # reading and writing the underlying file. + # * Create a string of a fixed size with ::string, then #read into it, or + # modify it using #set_value. # # # Interaction with string and file memory is performed by efficient low-level C # mechanisms like `memcpy`. # # The class is meant to be an utility for implementing more high-level - # mechanisms like Fiber::SchedulerInterface#io_read and - # Fiber::SchedulerInterface#io_write. + # mechanisms like Fiber::Scheduler#io_read and Fiber::Scheduler#io_write and + # parsing binary protocols. # - # **Examples of usage:** + # ## Examples of Usage # # Empty buffer: # @@ -81,7 +84,9 @@ class IO # File.read('test.txt') # # => "t--- buffer" # - # **The class is experimental and the interface is subject to change.** + # **The class is experimental and the interface is subject to change, this is + # especially true of file mappings which may be removed entirely in the + # future.** # class Buffer include Comparable @@ -91,10 +96,11 @@ class IO # - IO::Buffer.for(string) -> readonly io_buffer # - IO::Buffer.for(string) {|io_buffer| ... read/write io_buffer ...} # --> - # Creates a IO::Buffer from the given string's memory. Without a block a frozen - # internal copy of the string is created efficiently and used as the buffer - # source. When a block is provided, the buffer is associated directly with the - # string's internal buffer and updating the buffer will update the string. + # Creates a zero-copy IO::Buffer from the given string's memory. Without a block + # a frozen internal copy of the string is created efficiently and used as the + # buffer source. When a block is provided, the buffer is associated directly + # with the string's internal buffer and updating the buffer will update the + # string. # # Until #free is invoked on the buffer, either explicitly or via the garbage # collector, the source string will be locked and cannot be modified. @@ -136,8 +142,6 @@ class IO # mapping, you need to open a file in read-write mode, and explicitly pass # `flags` argument without IO::Buffer::IMMUTABLE. # - # Example: - # # File.write('test.txt', 'test') # # buffer = IO::Buffer.map(File.open('test.txt'), nil, 0, IO::Buffer::READONLY) @@ -169,9 +173,9 @@ class IO # rdoc-file=io_buffer.c # - IO::Buffer.string(length) {|io_buffer| ... read/write io_buffer ...} -> string # --> - # Creates a new string of the given length and yields a IO::Buffer instance to - # the block which uses the string as a source. The block is expected to write to - # the buffer and the string will be returned. + # Creates a new string of the given length and yields a zero-copy IO::Buffer + # instance to the block which uses the string as a source. The block is expected + # to write to the buffer and the string will be returned. # # IO::Buffer.string(4) do |buffer| # buffer.set_string("Ruby") @@ -316,8 +320,6 @@ class IO # # You can resize a freed buffer to re-allocate it. # - # Example: - # # buffer = IO::Buffer.for('test') # buffer.free # # => # @@ -381,8 +383,6 @@ class IO # in the buffer. For example, a `:u32` buffer type is a 32-bit unsigned integer # in little-endian format. # - # Example: - # # string = [1.5].pack('f') # # => "\x00\x00\xC0?" # IO::Buffer.for(string).get_value(:f32, 0) @@ -400,15 +400,35 @@ class IO # + # Returns a human-readable string representation of the buffer. The exact format + # is subject to change. + # + # buffer = IO::Buffer.for("Hello World") + # puts buffer.hexdump + # # 0x00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 Hello World + # + # As buffers are usually fairly big, you may want to limit the output by + # specifying the offset and length: + # + # puts buffer.hexdump(6, 5) + # # 0x00000006 57 6f 72 6c 64 World # def hexdump: () -> String # + # Inspect the buffer and report useful information about it's internal state. + # Only a limited portion of the buffer will be displayed in a hexdump style + # format. + # + # buffer = IO::Buffer.for("Hello World") + # puts buffer.inspect + # # # + # # 0x00000000 48 65 6c 6c 6f 20 57 6f 72 6c 64 Hello World # def inspect: () -> String @@ -445,8 +465,6 @@ class IO # system calls. You can only share a buffer between threads with appropriate # synchronisation techniques. # - # Example: - # # buffer = IO::Buffer.new(4) # buffer.locked? #=> false # @@ -476,8 +494,6 @@ class IO # Locking is not thread safe, but is a semantic used to ensure buffers don't # move while being used by a system call. # - # Example: - # # buffer.locked do # buffer.write(io) # theoretical system call interface # end @@ -503,7 +519,16 @@ class IO # rdoc-file=io_buffer.c # - null? -> true or false # --> - # If the buffer was freed with #free or was never allocated in the first place. + # If the buffer was freed with #free, transferred with #transfer, or was never + # allocated in the first place. + # + # buffer = IO::Buffer.new(0) + # buffer.null? #=> true + # + # buffer = IO::Buffer.new(4) + # buffer.null? #=> false + # buffer.free + # buffer.null? #=> true # def null?: () -> bool @@ -523,8 +548,6 @@ class IO # If `offset` is not given, it defaults to zero, i.e. the beginning of the # buffer. # - # Example: - # # IO::Buffer.for('test') do |buffer| # p buffer # # => @@ -561,8 +584,6 @@ class IO # If the `from` position is beyond the end of the file, the gap will be filled # with null (0 value) bytes. # - # Example: - # # out = File.open('output.txt', File::RDWR) # open for read/write, no truncation # IO::Buffer.for('1234567').pwrite(out, 2, 3, 1) # @@ -586,8 +607,6 @@ class IO # If `offset` is not given, it defaults to zero, i.e. the beginning of the # buffer. # - # Example: - # # IO::Buffer.for('test') do |buffer| # p buffer # # => @@ -636,8 +655,8 @@ class IO # rdoc-file=io_buffer.c # - set_string(string, [offset, [length, [source_offset]]]) -> size # --> - # Efficiently copy buffer from a source String into the buffer, at `offset` - # using `memcpy`. + # Efficiently copy from a source String into the buffer, at `offset` using + # `memcpy`. # # buf = IO::Buffer.new(8) # # => @@ -721,8 +740,6 @@ class IO # Raises RuntimeError if the `offset+length` is out of the current buffer's # bounds. # - # Example: - # # string = 'test' # buffer = IO::Buffer.for(string) # @@ -776,9 +793,8 @@ class IO # rdoc-file=io_buffer.c # - transfer -> new_io_buffer # --> - # Transfers ownership to a new buffer, deallocating the current one. - # - # Example: + # Transfers ownership of the underlying memory to a new buffer, causing the + # current buffer to become uninitialized. # # buffer = IO::Buffer.new('test') # other = buffer.transfer @@ -800,8 +816,8 @@ class IO # --> # Returns whether the buffer buffer is accessible. # - # A buffer becomes invalid if it is a slice of another buffer which has been - # freed. + # A buffer becomes invalid if it is a slice of another buffer (or string) which + # has been freed or re-allocated at a different address. # def valid?: () -> bool @@ -820,8 +836,6 @@ class IO # If `offset` is not given, it defaults to zero, i.e. the beginning of the # buffer. # - # Example: - # # out = File.open('output.txt', 'wb') # IO::Buffer.for('1234567').write(out, 3) # @@ -842,8 +856,6 @@ class IO # Unix, `VirtualAlloc` on Windows). The behavior can be forced by passing # IO::Buffer::MAPPED as a second parameter. # - # Examples - # # buffer = IO::Buffer.new(4) # # => # # # @@ -859,42 +871,109 @@ class IO # def initialize: (?Integer size, ?Integer flags) -> void + # + # Refers to big endian byte order, where the most significant byte is stored + # first. See #get_value for more details. + # BIG_ENDIAN: Integer + # + # The default buffer size, typically a (small) multiple of the PAGE_SIZE. Can be + # explicitly specified by setting the RUBY_IO_BUFFER_DEFAULT_SIZE environment + # variable. + # DEFAULT_SIZE: Integer + # + # Indicates that the memory in the buffer is owned by someone else. See + # #external? for more details. + # EXTERNAL: Integer + # + # Refers to the byte order of the host machine. See #get_value for more details. + # HOST_ENDIAN: Integer + # + # Indicates that the memory in the buffer is owned by the buffer. See #internal? + # for more details. + # INTERNAL: Integer + # + # Refers to little endian byte order, where the least significant byte is stored + # first. See #get_value for more details. + # LITTLE_ENDIAN: Integer + # + # Indicates that the memory in the buffer is locked and cannot be resized or + # freed. See #locked? and #locked for more details. + # LOCKED: Integer + # + # Indicates that the memory in the buffer is mapped by the operating system. See + # #mapped? for more details. + # MAPPED: Integer + # + # Refers to network byte order, which is the same as big endian. See #get_value + # for more details. + # NETWORK_ENDIAN: Integer + # + # The operating system page size. Used for efficient page-aligned memory + # allocations. + # PAGE_SIZE: Integer + # + # Indicates that the memory in the buffer is mapped privately and changes won't + # be replicated to the underlying file. See #private? for more details. + # PRIVATE: Integer + # + # Indicates that the memory in the buffer is read only, and attempts to modify + # it will fail. See #readonly? for more details. + # READONLY: Integer + # + # Raised when an operation would resize or re-allocate a locked buffer. + # class LockedError < RuntimeError end + # + # Raised when the buffer cannot be allocated for some reason, or you try to use + # a buffer that's not allocated. + # class AllocationError < RuntimeError end + # + # Raised when you try to write to a read-only buffer, or resize an external + # buffer. + # class AccessError < RuntimeError end + # + # Raised if you try to access a buffer slice which no longer references a valid + # memory range of the underlying source. + # class InvalidatedError < RuntimeError end + # + # Raised if the mask given to a binary operation is invalid, e.g. zero length or + # overlaps the target buffer. + # class MaskError < ArgumentError end end diff --git a/core/kernel.rbs b/core/kernel.rbs index 671a8fea8..efec896af 100644 --- a/core/kernel.rbs +++ b/core/kernel.rbs @@ -445,14 +445,14 @@ module Kernel : BasicObject # # Returns a new Complex object if the arguments are valid; otherwise raises an # exception if `exception` is `true`; otherwise returns `nil`. # - # With Numeric argument `abs`, returns `Complex.rect(abs, arg)` if the arguments - # are valid. + # With Numeric arguments `real` and `imag`, returns `Complex.rect(real, imag)` + # if the arguments are valid. # # With string argument `s`, returns a new Complex object if the argument is # valid; the string may have: diff --git a/core/match_data.rbs b/core/match_data.rbs index b117d0e03..551964d7c 100644 --- a/core/match_data.rbs +++ b/core/match_data.rbs @@ -81,6 +81,16 @@ class MatchData # m['foo'] # => "h" # m[:bar] # => "ge" # + # If multiple captures have the same name, returns the last matched substring. + # + # m = /(?.)(?.+)/.match("hoge") + # # => # + # m[:foo] #=> "oge" + # + # m = /\W(?.+)|\w(?.+)|(?.+)/.match("hoge") + # # + # m[:foo] #=> "oge" + # def []: (capture backref, ?nil) -> String? | (int start, int length) -> Array[String?] | (range[int?] range) -> Array[String?] @@ -278,24 +288,24 @@ class MatchData # rdoc-file=re.c # - named_captures(symbolize_names: false) -> hash # --> - # Returns a hash of the named captures; - # each key is a capture name; each value is its captured string or +nil+: + # Returns a hash of the named captures; each key is a capture name; each value + # is its captured string or `nil`: # - # m = /(?.)(.)(?.+)/.match("hoge") - # # => # - # m.named_captures # => {"foo"=>"h", "bar"=>"ge"} + # m = /(?.)(.)(?.+)/.match("hoge") + # # => # + # m.named_captures # => {"foo"=>"h", "bar"=>"ge"} # - # m = /(?.)(?.)/.match("01") - # # => # - # m.named_captures #=> {"a" => "0", "b" => "1"} + # m = /(?.)(?.)/.match("01") + # # => # + # m.named_captures #=> {"a" => "0", "b" => "1"} # - # m = /(?.)(?.)?/.match("0") - # # => # - # m.named_captures #=> {"a" => "0", "b" => nil} + # m = /(?.)(?.)?/.match("0") + # # => # + # m.named_captures #=> {"a" => "0", "b" => nil} # - # m = /(?.)(?.)/.match("01") - # # => # - # m.named_captures #=> {"a" => "1"} + # m = /(?.)(?.)/.match("01") + # # => # + # m.named_captures #=> {"a" => "1"} # # If keyword argument `symbolize_names` is given a true value, the keys in the # resulting hash are Symbols: diff --git a/core/module.rbs b/core/module.rbs index 127a6c83e..412c3aeba 100644 --- a/core/module.rbs +++ b/core/module.rbs @@ -1532,21 +1532,21 @@ class Module < Object # - mod.set_temporary_name(string) -> self # - mod.set_temporary_name(nil) -> self # --> - # Sets the temporary name of the module `mod`. This name is used as a prefix for - # the names of constants declared in `mod`. If the module is assigned a - # permanent name, the temporary name is discarded. + # Sets the temporary name of the module. This name is reflected in introspection + # of the module and the values that are related to it, such as instances, + # constants, and methods. # - # After a permanent name is assigned, a temporary name can no longer be set, and - # this method raises a RuntimeError. + # The name should be `nil` or non-empty string that is not a valid constant name + # (to avoid confusing between permanent and temporary names). # - # If the name given is not a string or is a zero length string, this method - # raises an ArgumentError. + # The method can be useful to distinguish dynamically generated classes and + # modules without assigning them to constants. # - # The temporary name must not be a valid constant name, to avoid confusion with - # actual constants. If you attempt to set a temporary name that is a a valid - # constant name, this method raises an ArgumentError. + # If the module is given a permanent name by assigning it to a constant, the + # temporary name is discarded. A temporary name can't be assigned to modules + # that have a permanent name. # - # If the given name is `nil`, the module becomes anonymous. + # If the given name is `nil`, the module becomes anonymous again. # # Example: # @@ -1559,15 +1559,20 @@ class Module < Object # m.set_temporary_name(nil) # => # # m.name #=> nil # - # n = Module.new - # n.set_temporary_name("fake_name") + # c = Class.new + # c.set_temporary_name("MyClass(with description)") # - # n::M = m - # n::M.name #=> "fake_name::M" - # N = n + # c.new # => # # - # N.name #=> "N" - # N::M.name #=> "N::M" + # c::M = m + # c::M.name #=> "MyClass(with description)::M" + # + # # Assigning to a constant replaces the name with a permanent one + # C = c + # + # C.name #=> "C" + # C::M.name #=> "C::M" + # c.new # => # # def set_temporary_name: (string?) -> self diff --git a/core/numeric.rbs b/core/numeric.rbs index d8247f4e6..613144948 100644 --- a/core/numeric.rbs +++ b/core/numeric.rbs @@ -248,24 +248,22 @@ class Numeric # - # Returns square of self. + # Returns the square of `self`. # def abs2: () -> Numeric # - # Returns 0 if the value is positive, pi otherwise. + # Returns zero if `self` is positive, Math::PI otherwise. # def angle: () -> Numeric # - # Returns 0 if the value is positive, pi otherwise. + # Returns zero if `self` is positive, Math::PI otherwise. # alias arg angle @@ -559,15 +557,15 @@ class Numeric def numerator: () -> Numeric # - # Returns 0 if the value is positive, pi otherwise. + # Returns zero if `self` is positive, Math::PI otherwise. # alias phase angle # - # Returns an array; [num.abs, num.arg]. + # Returns array `[self.abs, self.arg]`. # def polar: () -> [ Numeric, Numeric ] @@ -605,16 +603,15 @@ class Numeric def real?: () -> bool # - # Returns an array; [num, 0]. + # Returns array `[self, 0]`. # def rect: () -> [ Numeric, Numeric ] # - # Returns an array; [num, 0]. + # Returns array `[self, 0]`. # alias rectangular rect @@ -763,9 +760,9 @@ class Numeric # - # Returns the value as a complex. + # Returns `self` as a Complex object. # def to_c: () -> Complex diff --git a/core/object_space.rbs b/core/object_space.rbs index 8d94f93e2..d6167ac0b 100644 --- a/core/object_space.rbs +++ b/core/object_space.rbs @@ -166,6 +166,7 @@ module ObjectSpace # rdoc-file=gc.rb # - garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true) # --> + # Alias of GC.start # def self.garbage_collect: (?full_mark: bool, ?immediate_mark: bool, ?immediate_sweep: bool) -> void @@ -183,6 +184,7 @@ module ObjectSpace # rdoc-file=gc.rb # - garbage_collect(full_mark: true, immediate_mark: true, immediate_sweep: true) # --> + # Alias of GC.start # def garbage_collect: (?full_mark: bool, ?immediate_mark: bool, ?immediate_sweep: bool) -> void end diff --git a/core/object_space/weak_key_map.rbs b/core/object_space/weak_key_map.rbs index 77601f82c..f02851df4 100644 --- a/core/object_space/weak_key_map.rbs +++ b/core/object_space/weak_key_map.rbs @@ -1,10 +1,62 @@ %a{annotate:rdoc:skip} module ObjectSpace # - # An ObjectSpace::WeakKeyMap object holds references to any objects, but objects - # uses as keys can be garbage collected. + # An ObjectSpace::WeakKeyMap is a key-value map that holds weak references to + # its keys, so they can be garbage collected when there is no more references. # - # Objects used as values can't be garbage collected until the key is. + # Unlike ObjectSpace::WeakMap: + # + # * references to values are *strong*, so they aren't garbage collected while + # they are in the map; + # * keys are compared by value (using Object#eql?), not by identity; + # * only garbage-collectable objects can be used as keys. + # + # map = ObjectSpace::WeakKeyMap.new + # val = Time.new(2023, 12, 7) + # key = "name" + # map[key] = val + # + # # Value is fetched by equality: the instance of string "name" is + # # different here, but it is equal to the key + # map["name"] #=> 2023-12-07 00:00:00 +0200 + # + # val = nil + # GC.start + # # There is no more references to `val`, yet the pair isn't + # # garbage-collected. + # map["name"] #=> 2023-12-07 00:00:00 +0200 + # + # key = nil + # GC.start + # # There is no more references to `key`, key and value are + # # garbage-collected. + # map["name"] #=> nil + # + # + # (Note that GC.start is used here only for demonstrational purposes and might + # not always lead to demonstrated results.) + # + # The collection is especially useful for implementing caches of lightweight + # value objects, so that only one copy of each value representation would be + # stored in memory, but the copies that aren't used would be garbage-collected. + # + # CACHE = ObjectSpace::WeakKeyMap + # + # def make_value(**) + # val = ValueObject.new(**) + # if (existing = @cache.getkey(val)) + # # if the object with this value exists, we return it + # existing + # else + # # otherwise, put it in the cache + # @cache[val] = true + # val + # end + # end + # + # This will result in `make_value` returning the same object for same set of + # attributes always, but the values that aren't needed anymore woudn't be + # sitting in the cache forever. # class WeakKeyMap[Key, Value] public @@ -23,7 +75,7 @@ module ObjectSpace # rdoc-file=weakmap.c # - map[key] = value -> value # --> - # Associates the given `value` with the given `key`; returns `value`. + # Associates the given `value` with the given `key` # # The reference to `key` is weak, so when there is no other reference to `key` # it may be garbage collected. @@ -51,7 +103,8 @@ module ObjectSpace # If no block is given and `key` is found, deletes the entry and returns the # associated value: # m = ObjectSpace::WeakKeyMap.new - # m["foo"] = 1 + # key = "foo" # to hold reference to the key + # m[key] = 1 # m.delete("foo") # => 1 # m["foo"] # => nil # @@ -60,13 +113,14 @@ module ObjectSpace # If a block is given and `key` is found, ignores the block, deletes the entry, # and returns the associated value: # m = ObjectSpace::WeakKeyMap.new - # m["foo"] = 2 - # h.delete("foo") { |key| raise 'Will never happen'} # => 2 + # key = "foo" # to hold reference to the key + # m[key] = 2 + # m.delete("foo") { |key| raise 'Will never happen'} # => 2 # - # If a block is given and `key` is not found, calls the block and returns the - # block's return value: + # If a block is given and `key` is not found, yields the `key` to the block and + # returns the block's return value: # m = ObjectSpace::WeakKeyMap.new - # h.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found" + # m.delete("nosuch") { |key| "Key #{key} not found" } # => "Key nosuch not found" # def delete: (Key) -> Value? | [T] (Key) { (Key) -> T } -> (Value | T) @@ -77,6 +131,19 @@ module ObjectSpace # --> # Returns the existing equal key if it exists, otherwise returns `nil`. # + # This might be useful for implementing caches, so that only one copy of some + # object would be used everywhere in the program: + # + # value = {amount: 1, currency: 'USD'} + # + # # Now if we put this object in a cache: + # cache = ObjectSpace::WeakKeyMap.new + # cache[value] = true + # + # # ...we can always extract from there and use the same object: + # copy = cache.getkey({amount: 1, currency: 'USD'}) + # copy.object_id == value.object_id #=> true + # def getkey: (untyped) -> Key? # # Returns `true` if `key` is a key in `self`, otherwise `false`. # diff --git a/core/process.rbs b/core/process.rbs index 1fd4dd26b..35d18506b 100644 --- a/core/process.rbs +++ b/core/process.rbs @@ -1788,7 +1788,6 @@ end # stat = $? # => # # stat.class # => Process::Status # stat.to_i # => 25344 -# stat >> 8 # => 99 # stat.stopped? # => false # stat.exited? # => true # stat.exitstatus # => 99 @@ -1798,7 +1797,8 @@ class Process::Status < Object # rdoc-file=process.c # - stat & mask -> integer # --> - # This method is deprecated; use other attribute methods. + # This method is deprecated as #to_i value is system-specific; use predicate + # methods like #exited? or #stopped?, or getters like #exitstatus or #stopsig. # # Returns the logical AND of the value of #to_i with `mask`: # @@ -1828,7 +1828,8 @@ class Process::Status < Object # rdoc-file=process.c # - stat >> places -> integer # --> - # This method is deprecated; use other predicate methods. + # This method is deprecated as #to_i value is system-specific; use predicate + # methods like #exited? or #stopped?, or getters like #exitstatus or #stopsig. # # Returns the value of #to_i, shifted `places` to the right: # diff --git a/core/range.rbs b/core/range.rbs index d468671d8..ede44f5ae 100644 --- a/core/range.rbs +++ b/core/range.rbs @@ -871,15 +871,16 @@ class Range[out Elem] < Object # (1..2).overlap?(3..4) # => false # (1...3).overlap?(3..4) # => false # - # This method assumes that there is no minimum value because Ruby lacks a - # standard method for determining minimum values. This assumption is invalid. - # For example, there is no value smaller than `-Float::INFINITY`, making - # `(...-Float::INFINITY)` an empty set. Consequently, `(...-Float::INFINITY)` - # has no elements in common with itself, yet - # `(...-Float::INFINITY).overlap?((...-Float::INFINITY)) returns true due to - # this assumption. In general, if r = (...minimum); r.overlap?(r)` returns - # `true`, where `minimum` is a value that no value is smaller than. Such values - # include `-Float::INFINITY`, `[]`, `""`, and classes without subclasses. + # Note that the method wouldn't make any assumptions about the beginless range + # being actually empty, even if its upper bound is the minimum possible value of + # its type, so all this would return `true`: + # + # (...-Float::INFINITY).overlap?(...-Float::INFINITY) # => true + # (..."").overlap?(..."") # => true + # (...[]).overlap?(...[]) # => true + # + # Even if those ranges are effectively empty (no number can be smaller than + # `-Float::INFINITY`), they are still considered overlapping with themselves. # # Related: Range#cover?. # diff --git a/core/refinement.rbs b/core/refinement.rbs index 931ddc3e4..91fbc487b 100644 --- a/core/refinement.rbs +++ b/core/refinement.rbs @@ -46,15 +46,24 @@ class Refinement < Module # rdoc-file=eval.c # - refined_class -> class # --> + # Deprecated; prefer #target. + # # Return the class refined by the receiver. # def refined_class: () -> Module # # Return the class or module refined by the receiver. # + # module M + # refine String do + # end + # end + # + # M.refinements[0].target # => String + # def target: () -> Module end diff --git a/core/string.rbs b/core/string.rbs index 5a5ba99f5..52dfa02ef 100644 --- a/core/string.rbs +++ b/core/string.rbs @@ -3163,31 +3163,30 @@ class String # - # Returns a complex which denotes the string form. The parser ignores leading - # whitespaces and trailing garbage. Any digit sequences can be separated by an - # underscore. Returns zero for null or garbage string. - # - # '9'.to_c #=> (9+0i) - # '2.5'.to_c #=> (2.5+0i) - # '2.5/1'.to_c #=> ((5/2)+0i) - # '-3/2'.to_c #=> ((-3/2)+0i) - # '-i'.to_c #=> (0-1i) - # '45i'.to_c #=> (0+45i) - # '3-4i'.to_c #=> (3-4i) - # '-4e2-4e-2i'.to_c #=> (-400.0-0.04i) - # '-0.0-0.0i'.to_c #=> (-0.0-0.0i) - # '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i) - # 'ruby'.to_c #=> (0+0i) - # - # Polar form: - # include Math - # "1.0@0".to_c #=> (1+0.0i) - # "1.0@#{PI/2}".to_c #=> (0.0+1i) - # "1.0@#{PI}".to_c #=> (-1+0.0i) - # - # See Kernel.Complex. + # - to_c -> complex + # --> + # Returns `self` interpreted as a Complex object; leading whitespace and + # trailing garbage are ignored: + # + # '9'.to_c # => (9+0i) + # '2.5'.to_c # => (2.5+0i) + # '2.5/1'.to_c # => ((5/2)+0i) + # '-3/2'.to_c # => ((-3/2)+0i) + # '-i'.to_c # => (0-1i) + # '45i'.to_c # => (0+45i) + # '3-4i'.to_c # => (3-4i) + # '-4e2-4e-2i'.to_c # => (-400.0-0.04i) + # '-0.0-0.0i'.to_c # => (-0.0-0.0i) + # '1/2+3/4i'.to_c # => ((1/2)+(3/4)*i) + # '1.0@0'.to_c # => (1+0.0i) + # "1.0@#{Math::PI/2}".to_c # => (0.0+1i) + # "1.0@#{Math::PI}".to_c # => (-1+0.0i) + # + # Returns Complex zero if the string cannot be converted: + # + # 'ruby'.to_c # => (0+0i) + # + # See Kernel#Complex. # def to_c: () -> Complex diff --git a/core/thread.rbs b/core/thread.rbs index c37787c95..5abca1dd0 100644 --- a/core/thread.rbs +++ b/core/thread.rbs @@ -1626,8 +1626,8 @@ class Thread::Queue < Object # rdoc-file=thread_sync.c # - freeze # --> - # Raises an exception: - # Queue.new.freeze # Raises TypeError (cannot freeze #) + # The queue can't be frozen, so this method raises an exception: + # Thread::Queue.new.freeze # Raises TypeError (cannot freeze #) # def freeze: () -> bot @@ -1711,8 +1711,8 @@ class Thread::SizedQueue < Thread::Queue # rdoc-file=thread_sync.c # - freeze # --> - # Raises an exception: - # Queue.new.freeze # Raises TypeError (cannot freeze #) + # The queue can't be frozen, so this method raises an exception: + # Thread::Queue.new.freeze # Raises TypeError (cannot freeze #) # def freeze: () -> bot diff --git a/core/trace_point.rbs b/core/trace_point.rbs index 38bc8d802..af65af09e 100644 --- a/core/trace_point.rbs +++ b/core/trace_point.rbs @@ -44,6 +44,8 @@ # : return from a C-language routine # `:raise` # : raise an exception +# `:rescue` +# : rescue an exception # `:b_call` # : event hook at block entry # `:b_return` @@ -205,7 +207,7 @@ class TracePoint < Object # --> # Return the generated binding object from event. # - # Note that for `c_call` and `c_return` events, the method will return `nil`, + # Note that for `:c_call` and `:c_return` events, the method will return `nil`, # since C methods themselves do not have bindings. # def binding: () -> Binding? @@ -416,7 +418,8 @@ class TracePoint < Object # rdoc-file=trace_point.rb # - raised_exception() # --> - # Value from exception raised on the `:raise` event + # Value from exception raised on the `:raise` event, or rescued on the `:rescue` + # event. # def raised_exception: () -> untyped @@ -424,7 +427,7 @@ class TracePoint < Object # rdoc-file=trace_point.rb # - return_value() # --> - # Return value from `:return`, `c_return`, and `b_return` event + # Return value from `:return`, `:c_return`, and `:b_return` event # def return_value: () -> untyped @@ -435,7 +438,7 @@ class TracePoint < Object # Return the trace object during event # # Same as the following, except it returns the correct object (the method - # receiver) for `c_call` and `c_return` events: + # receiver) for `:c_call` and `:c_return` events: # # trace.binding.eval('self') # diff --git a/stdlib/bigdecimal/0/big_decimal.rbs b/stdlib/bigdecimal/0/big_decimal.rbs index d4e6a6976..5c8c5d58a 100644 --- a/stdlib/bigdecimal/0/big_decimal.rbs +++ b/stdlib/bigdecimal/0/big_decimal.rbs @@ -1711,61 +1711,60 @@ class Complex # - # Performs division. + # Returns the quotient of `self` and `numeric`: # - # Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i) - # Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i) - # Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i) - # Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i) - # Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i) + # Complex(2, 3) / Complex(2, 3) # => ((1/1)+(0/1)*i) + # Complex(900) / Complex(1) # => ((900/1)+(0/1)*i) + # Complex(-2, 9) / Complex(-9, 2) # => ((36/85)-(77/85)*i) + # Complex(9, 8) / 4 # => ((9/4)+(2/1)*i) + # Complex(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def /: (BigDecimal) -> Complex | ... # - # Performs multiplication. + # Returns the product of `self` and `numeric`: # - # Complex(2, 3) * Complex(2, 3) #=> (-5+12i) - # Complex(900) * Complex(1) #=> (900+0i) - # Complex(-2, 9) * Complex(-9, 2) #=> (0-85i) - # Complex(9, 8) * 4 #=> (36+32i) - # Complex(20, 9) * 9.8 #=> (196.0+88.2i) + # Complex(2, 3) * Complex(2, 3) # => (-5+12i) + # Complex(900) * Complex(1) # => (900+0i) + # Complex(-2, 9) * Complex(-9, 2) # => (0-85i) + # Complex(9, 8) * 4 # => (36+32i) + # Complex(20, 9) * 9.8 # => (196.0+88.2i) # def *: (BigDecimal) -> Complex | ... # - # Performs addition. + # Returns the sum of `self` and `numeric`: # - # Complex(2, 3) + Complex(2, 3) #=> (4+6i) - # Complex(900) + Complex(1) #=> (901+0i) - # Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i) - # Complex(9, 8) + 4 #=> (13+8i) - # Complex(20, 9) + 9.8 #=> (29.8+9i) + # Complex(2, 3) + Complex(2, 3) # => (4+6i) + # Complex(900) + Complex(1) # => (901+0i) + # Complex(-2, 9) + Complex(-9, 2) # => (-11+11i) + # Complex(9, 8) + 4 # => (13+8i) + # Complex(20, 9) + 9.8 # => (29.8+9i) # def +: (BigDecimal) -> Complex | ... # - # Performs subtraction. + # Returns the difference of `self` and `numeric`: # - # Complex(2, 3) - Complex(2, 3) #=> (0+0i) - # Complex(900) - Complex(1) #=> (899+0i) - # Complex(-2, 9) - Complex(-9, 2) #=> (7+7i) - # Complex(9, 8) - 4 #=> (5+8i) - # Complex(20, 9) - 9.8 #=> (10.2+9i) + # Complex(2, 3) - Complex(2, 3) # => (0+0i) + # Complex(900) - Complex(1) # => (899+0i) + # Complex(-2, 9) - Complex(-9, 2) # => (7+7i) + # Complex(9, 8) - 4 # => (5+8i) + # Complex(20, 9) - 9.8 # => (10.2+9i) # def -: (BigDecimal) -> Complex | ... diff --git a/stdlib/pty/0/pty.rbs b/stdlib/pty/0/pty.rbs index 11a4aab36..25532cf13 100644 --- a/stdlib/pty/0/pty.rbs +++ b/stdlib/pty/0/pty.rbs @@ -74,13 +74,7 @@ module PTY # def self.check: (Integer pid, ?boolish raise) -> Process::Status? - # + # # Spawns the specified command on a newly allocated pty. You can also use the # alias ::getpty. # diff --git a/stdlib/socket/0/addrinfo.rbs b/stdlib/socket/0/addrinfo.rbs index dd2c14032..de11e7a1a 100644 --- a/stdlib/socket/0/addrinfo.rbs +++ b/stdlib/socket/0/addrinfo.rbs @@ -1,3 +1,7 @@ +# +# The Addrinfo class maps `struct addrinfo` to ruby. This structure identifies +# an Internet host and a service. +# class Addrinfo #