diff --git a/core/array.rbs b/core/array.rbs index 1adfc20b15..a05741c692 100644 --- a/core/array.rbs +++ b/core/array.rbs @@ -1,13 +1,39 @@ # -# An Array is an ordered, integer-indexed collection of objects, called -# *elements*. Any object (even another array) may be an array element, and an -# array can contain objects of different types. +# An Array object is an ordered, integer-indexed collection of objects, called +# *elements*; the object represents an [array data +# structure](https://en.wikipedia.org/wiki/Array_(data_structure)). +# +# An element may be any object (even another array); elements may be any mixture +# of objects of different types. +# +# Important data structures that use arrays include: +# +# * [Coordinate vector](https://en.wikipedia.org/wiki/Coordinate_vector). +# * [Matrix](https://en.wikipedia.org/wiki/Matrix_(mathematics)). +# * [Heap](https://en.wikipedia.org/wiki/Heap_(data_structure)). +# * [Hash table](https://en.wikipedia.org/wiki/Hash_table). +# * [Deque (double-ended +# queue)](https://en.wikipedia.org/wiki/Double-ended_queue). +# * [Queue](https://en.wikipedia.org/wiki/Queue_(abstract_data_type)). +# * [Stack](https://en.wikipedia.org/wiki/Stack_(abstract_data_type)). +# +# There are also array-like data structures: +# +# * [Associative array](https://en.wikipedia.org/wiki/Associative_array) (see +# Hash). +# * [Directory](https://en.wikipedia.org/wiki/Directory_(computing)) (see +# Dir). +# * [Environment](https://en.wikipedia.org/wiki/Environment_variable) (see +# ENV). +# * [Set](https://en.wikipedia.org/wiki/Set_(abstract_data_type)) (see Set). +# * [String](https://en.wikipedia.org/wiki/String_(computer_science)) (see +# String). # # ## Array Indexes # # Array indexing starts at 0, as in C or Java. # -# A positive index is an offset from the first element: +# A non-negative index is an offset from the first element: # # * Index 0 indicates the first element. # * Index 1 indicates the second element. @@ -19,6 +45,8 @@ # * Index -2 indicates the next-to-last element. # * ... # +# ### In-Range and Out-of-Range Indexes +# # A non-negative index is *in range* if and only if it is smaller than the size # of the array. For a 3-element array: # @@ -31,8 +59,10 @@ # * Indexes -1 through -3 are in range. # * Index -4 is out of range. # +# ### Effective Index +# # Although the effective index into an array is always an integer, some methods -# (both within and outside of class Array) accept one or more non-integer +# (both within class Array and elsewhere) accept one or more non-integer # arguments that are [integer-convertible # objects](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). # @@ -120,7 +150,7 @@ # ## Example Usage # # In addition to the methods it mixes in through the Enumerable module, the -# Array class has proprietary methods for accessing, searching and otherwise +# `Array` class has proprietary methods for accessing, searching and otherwise # manipulating arrays. # # Some of the more common ones are illustrated below. @@ -168,7 +198,7 @@ # # arr.drop(3) #=> [4, 5, 6] # -# ## Obtaining Information about an Array +# ## Obtaining Information about an `Array` # # Arrays keep track of their own length at all times. To query an array about # the number of elements it contains, use #length, #count or #size. @@ -206,7 +236,7 @@ # arr.insert(3, 'orange', 'pear', 'grapefruit') # #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6] # -# ## Removing Items from an Array +# ## Removing Items from an `Array` # # The method #pop removes the last element in an array and returns it: # @@ -247,10 +277,10 @@ # # ## Iterating over Arrays # -# Like all classes that include the Enumerable module, Array has an each method, -# which defines what elements should be iterated over and how. In case of -# Array's #each, all elements in the Array instance are yielded to the supplied -# block in sequence. +# Like all classes that include the Enumerable module, `Array` has an each +# method, which defines what elements should be iterated over and how. In case +# of Array's #each, all elements in the `Array` instance are yielded to the +# supplied block in sequence. # # Note that this operation leaves the array unchanged. # @@ -275,7 +305,7 @@ # arr.map! {|a| a**2} #=> [1, 4, 9, 16, 25] # arr #=> [1, 4, 9, 16, 25] # -# ## Selecting Items from an Array +# ## Selecting Items from an `Array` # # Elements can be selected from an array according to criteria defined in a # block. The selection can happen in a destructive or a non-destructive manner. @@ -308,13 +338,13 @@ # # ## What's Here # -# First, what's elsewhere. Class Array: +# First, what's elsewhere. Class `Array`: # # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). # * Includes [module Enumerable](rdoc-ref:Enumerable@What-27s+Here), which # provides dozens of additional methods. # -# Here, class Array provides methods that are useful for: +# Here, class `Array` provides methods that are useful for: # # * [Creating an Array](rdoc-ref:Array@Methods+for+Creating+an+Array) # * [Querying](rdoc-ref:Array@Methods+for+Querying) @@ -327,31 +357,33 @@ # * [Converting](rdoc-ref:Array@Methods+for+Converting) # * [And more....](rdoc-ref:Array@Other+Methods) # -# ### Methods for Creating an Array +# ### Methods for Creating an `Array` # # * ::[]: Returns a new array populated with given objects. # * ::new: Returns a new array. # * ::try_convert: Returns a new array created from a given object. # +# See also [Creating Arrays](rdoc-ref:Array@Creating+Arrays). +# # ### Methods for Querying # -# * #length, #size: Returns the count of elements. -# * #include?: Returns whether any element `==` a given object. -# * #empty?: Returns whether there are no elements. # * #all?: Returns whether all elements meet a given criterion. # * #any?: Returns whether any element meets a given criterion. +# * #count: Returns the count of elements that meet a given criterion. +# * #empty?: Returns whether there are no elements. +# * #find_index (aliased as #index): Returns the index of the first element +# that meets a given criterion. +# * #hash: Returns the integer hash code. +# * #include?: Returns whether any element `==` a given object. +# * #length (aliased as #size): Returns the count of elements. # * #none?: Returns whether no element `==` a given object. # * #one?: Returns whether exactly one element `==` a given object. -# * #count: Returns the count of elements that meet a given criterion. -# * #find_index, #index: Returns the index of the first element that meets a -# given criterion. # * #rindex: Returns the index of the last element that meets a given # criterion. -# * #hash: Returns the integer hash code. # # ### Methods for Comparing # -# * #<=>: Returns -1, 0, or 1 * as `self` is less than, equal to, or greater +# * #<=>: Returns -1, 0, or 1, as `self` is less than, equal to, or greater # than a given object. # * #==: Returns whether each element in `self` is `==` to the corresponding # element in a given object. @@ -362,78 +394,86 @@ # # These methods do not modify `self`. # -# * #[]: Returns one or more elements. +# * #[] (aliased as #slice): Returns consecutive elements as determined by a +# given argument. +# * #assoc: Returns the first element that is an array whose first element +# `==` a given object. +# * #at: Returns the element at a given offset. +# * #bsearch: Returns an element selected via a binary search as determined by +# a given block. +# * #bsearch_index: Returns the index of an element selected via a binary +# search as determined by a given block. +# * #compact: Returns an array containing all non-`nil` elements. +# * #dig: Returns the object in nested objects that is specified by a given +# index and additional arguments. +# * #drop: Returns trailing elements as determined by a given index. +# * #drop_while: Returns trailing elements as determined by a given block. # * #fetch: Returns the element at a given offset. +# * #fetch_values: Returns elements at given offsets. # * #first: Returns one or more leading elements. # * #last: Returns one or more trailing elements. -# * #max: Returns one or more maximum-valued elements, as determined by `<=>` +# * #max: Returns one or more maximum-valued elements, as determined by `#<=>` # or a given block. -# * #min: Returns one or more minimum-valued elements, as determined by `<=>` +# * #min: Returns one or more minimum-valued elements, as determined by `#<=>` # or a given block. # * #minmax: Returns the minimum-valued and maximum-valued elements, as -# determined by `<=>` or a given block. -# * #assoc: Returns the first element that is an array whose first element -# `==` a given object. +# determined by `#<=>` or a given block. # * #rassoc: Returns the first element that is an array whose second element # `==` a given object. -# * #at: Returns the element at a given offset. -# * #values_at: Returns the elements at given offsets. -# * #dig: Returns the object in nested objects that is specified by a given -# index and additional arguments. -# * #drop: Returns trailing elements as determined by a given index. -# * #take: Returns leading elements as determined by a given index. -# * #drop_while: Returns trailing elements as determined by a given block. -# * #take_while: Returns leading elements as determined by a given block. -# * #slice: Returns consecutive elements as determined by a given argument. -# * #sort: Returns all elements in an order determined by `<=>` or a given +# * #reject: Returns an array containing elements not rejected by a given # block. # * #reverse: Returns all elements in reverse order. -# * #compact: Returns an array containing all non-`nil` elements. -# * #select, #filter: Returns an array containing elements selected by a given -# block. -# * #uniq: Returns an array containing non-duplicate elements. # * #rotate: Returns all elements with some rotated from one end to the other. -# * #bsearch: Returns an element selected via a binary search as determined by -# a given block. -# * #bsearch_index: Returns the index of an element selected via a binary -# search as determined by a given block. # * #sample: Returns one or more random elements. +# * #select (aliased as #filter): Returns an array containing elements +# selected by a given block. # * #shuffle: Returns elements in a random order. +# * #sort: Returns all elements in an order determined by `#<=>` or a given +# block. +# * #take: Returns leading elements as determined by a given index. +# * #take_while: Returns leading elements as determined by a given block. +# * #uniq: Returns an array containing non-duplicate elements. +# * #values_at: Returns the elements at given offsets. # # ### Methods for Assigning # # These methods add, replace, or reorder elements in `self`. # +# * #<<: Appends an element. # * #[]=: Assigns specified elements with a given object. -# * #push, #append, #<<: Appends trailing elements. -# * #unshift, #prepend: Prepends leading elements. -# * #insert: Inserts given objects at a given offset; does not replace -# elements. # * #concat: Appends all elements from given arrays. # * #fill: Replaces specified elements with specified objects. -# * #replace: Replaces the content of `self` with the content of a given -# array. +# * #flatten!: Replaces each nested array in `self` with the elements from +# that array. +# * #initialize_copy (aliased as #replace): Replaces the content of `self` +# with the content of a given array. +# * #insert: Inserts given objects at a given offset; does not replace +# elements. +# * #push (aliased as #append): Appends elements. # * #reverse!: Replaces `self` with its elements reversed. # * #rotate!: Replaces `self` with its elements rotated. # * #shuffle!: Replaces `self` with its elements in random order. -# * #sort!: Replaces `self` with its elements sorted, as determined by `<=>` +# * #sort!: Replaces `self` with its elements sorted, as determined by `#<=>` # or a given block. # * #sort_by!: Replaces `self` with its elements sorted, as determined by a # given block. +# * #unshift (aliased as #prepend): Prepends leading elements. # # ### Methods for Deleting # # Each of these methods removes elements from `self`: # -# * #pop: Removes and returns the last element. -# * #shift: Removes and returns the first element. +# * #clear: Removes all elements. # * #compact!: Removes all `nil` elements. # * #delete: Removes elements equal to a given object. # * #delete_at: Removes the element at a given offset. # * #delete_if: Removes elements specified by a given block. # * #keep_if: Removes elements not specified by a given block. +# * #pop: Removes and returns the last element. # * #reject!: Removes elements specified by a given block. -# * #select!, #filter!: Removes elements not specified by a given block. +# * #select! (aliased as #filter!): Removes elements not specified by a given +# block. +# * #shift: Removes and returns the first element. # * #slice!: Removes and returns a sequence of elements. # * #uniq!: Removes duplicates. # @@ -441,54 +481,54 @@ # # * #&: Returns an array containing elements found both in `self` and a given # array. -# * #intersection: Returns an array containing elements found both in `self` -# and in each given array. # * #+: Returns an array containing all elements of `self` followed by all # elements of a given array. # * #-: Returns an array containing all elements of `self` that are not found # in a given array. -# * #|: Returns an array containing all elements of `self` and all elements of +# * #|: Returns an array containing all element of `self` and all elements of # a given array, duplicates removed. -# * #union: Returns an array containing all elements of `self` and all -# elements of given arrays, duplicates removed. # * #difference: Returns an array containing all elements of `self` that are # not found in any of the given arrays.. +# * #intersection: Returns an array containing elements found both in `self` +# and in each given array. # * #product: Returns or yields all combinations of elements from `self` and # given arrays. +# * #reverse: Returns an array containing all elements of `self` in reverse +# order. +# * #union: Returns an array containing all elements of `self` and all +# elements of given arrays, duplicates removed. # # ### Methods for Iterating # -# * #each: Passes each element to a given block. -# * #reverse_each: Passes each element, in reverse order, to a given block. -# * #each_index: Passes each element index to a given block. -# * #cycle: Calls a given block with each element, then does so again, for a -# specified number of times, or forever. # * #combination: Calls a given block with combinations of elements of `self`; # a combination does not use the same element more than once. +# * #cycle: Calls a given block with each element, then does so again, for a +# specified number of times, or forever. +# * #each: Passes each element to a given block. +# * #each_index: Passes each element index to a given block. # * #permutation: Calls a given block with permutations of elements of `self`; # a permutation does not use the same element more than once. # * #repeated_combination: Calls a given block with combinations of elements # of `self`; a combination may use the same element more than once. # * #repeated_permutation: Calls a given block with permutations of elements # of `self`; a permutation may use the same element more than once. +# * #reverse_each: Passes each element, in reverse order, to a given block. # # ### Methods for Converting # -# * #map, #collect: Returns an array containing the block return-value for -# each element. -# * #map!, #collect!: Replaces each element with a block return-value. +# * #collect (aliased as #map): Returns an array containing the block +# return-value for each element. +# * #collect! (aliased as #map!): Replaces each element with a block +# return-value. # * #flatten: Returns an array that is a recursive flattening of `self`. -# * #flatten!: Replaces each nested array in `self` with the elements from -# that array. -# * #inspect, #to_s: Returns a new String containing the elements. +# * #inspect (aliased as #to_s): Returns a new String containing the elements. # * #join: Returns a newsString containing the elements joined by the field # separator. # * #to_a: Returns `self` or a new array containing all elements. # * #to_ary: Returns `self`. # * #to_h: Returns a new hash formed from the elements. # * #transpose: Transposes `self`, which must be an array of arrays. -# * #zip: Returns a new array of arrays containing `self` and given arrays; -# follow the link for details. +# * #zip: Returns a new array of arrays containing `self` and given arrays. # # ### Other Methods # @@ -499,7 +539,6 @@ # * With string argument `field_separator`, a new string that is # equivalent to `join(field_separator)`. # -# * #abbrev: Returns a hash of unambiguous abbreviations for elements. # * #pack: Packs the elements into a binary sequence. # * #sum: Returns a sum of elements according to either `+` or a given block. # @@ -511,44 +550,55 @@ class Array[unchecked out Elem] < Object # rdoc-file=array.c # - Array.new -> new_empty_array # - Array.new(array) -> new_array - # - Array.new(size) -> new_array - # - Array.new(size, default_value) -> new_array - # - Array.new(size) {|index| ... } -> new_array + # - Array.new(size, default_value = nil) -> new_array + # - Array.new(size = 0) {|index| ... } -> new_array # --> - # Returns a new Array. + # Returns a new array. # - # With no block and no arguments, returns a new empty Array object. + # With no block and no argument given, returns a new empty array: # - # With no block and a single Array argument `array`, returns a new Array formed - # from `array`: + # Array.new # => [] # - # a = Array.new([:foo, 'bar', 2]) - # a.class # => Array - # a # => [:foo, "bar", 2] + # With no block and array argument given, returns a new array with the same + # elements: + # + # Array.new([:foo, 'bar', 2]) # => [:foo, "bar", 2] + # + # With no block and integer argument given, returns a new array containing that + # many instances of the given `default_value`: # - # With no block and a single Integer argument `size`, returns a new Array of the - # given size whose elements are all `nil`: + # Array.new(0) # => [] + # Array.new(3) # => [nil, nil, nil] + # Array.new(2, 3) # => [3, 3] # - # a = Array.new(3) - # a # => [nil, nil, nil] + # With a block given, returns an array of the given `size`; calls the block with + # each `index` in the range `(0...size)`; the element at that `index` in the + # returned array is the blocks return value: # - # With no block and arguments `size` and `default_value`, returns an Array of - # the given size; each element is that same `default_value`: + # Array.new(3) {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"] # - # a = Array.new(3, 'x') - # a # => ['x', 'x', 'x'] + # A common pitfall for new Rubyists is providing an expression as + # `default_value`: # - # With a block and argument `size`, returns an Array of the given size; the - # block is called with each successive integer `index`; the element for that - # `index` is the return value from the block: + # array = Array.new(2, {}) + # array # => [{}, {}] + # array[0][:a] = 1 + # array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object # - # a = Array.new(3) {|index| "Element #{index}" } - # a # => ["Element 0", "Element 1", "Element 2"] + # If you want the elements of the array to be distinct, you should pass a block: # - # Raises ArgumentError if `size` is negative. + # array = Array.new(2) { {} } + # array # => [{}, {}] + # array[0][:a] = 1 + # array # => [{a: 1}, {}], as array[0] and array[1] are different objects # - # With a block and no argument, or a single argument `0`, ignores the block and - # returns a new empty Array. + # Raises TypeError if the first argument is not either an array or an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects)). + # Raises ArgumentError if the first argument is a negative integer. + # + # Related: see [Methods for Creating an + # Array](rdoc-ref:Array@Methods+for+Creating+an+Array). # def initialize: () -> void | (::Array[Elem] ary) -> void @@ -559,11 +609,14 @@ class Array[unchecked out Elem] < Object # rdoc-file=array.c # - [](*args) # --> - # Returns a new array populated with the given objects. + # Returns a new array, populated with the given objects: + # + # Array[1, 'a', /^A/] # => [1, "a", /^A/] + # Array[] # => [] + # Array.[](1, 'a', /^A/) # => [1, "a", /^A/] # - # Array.[]( 1, 'a', /^A/) # => [1, "a", /^A/] - # Array[ 1, 'a', /^A/ ] # => [1, "a", /^A/] - # [ 1, 'a', /^A/ ] # => [1, "a", /^A/] + # Related: see [Methods for Creating an + # Array](rdoc-ref:Array@Methods+for+Creating+an+Array). # def self.[]: [U] (*U) -> ::Array[U] @@ -571,49 +624,58 @@ class Array[unchecked out Elem] < Object # rdoc-file=array.c # - Array.try_convert(object) -> object, new_array, or nil # --> - # If `object` is an Array object, returns `object`. + # Attempts to return an array, based on the given `object`. # - # Otherwise if `object` responds to `:to_ary`, calls `object.to_ary` and returns - # the result. + # If `object` is an array, returns `object`. # - # Returns `nil` if `object` does not respond to `:to_ary` + # Otherwise if `object` responds to `:to_ary`. calls `object.to_ary`: if the + # return value is an array or `nil`, returns that value; if not, raises + # TypeError. # - # Raises an exception unless `object.to_ary` returns an Array object. + # Otherwise returns `nil`. + # + # Related: see [Methods for Creating an + # Array](rdoc-ref:Array@Methods+for+Creating+an+Array). # def self.try_convert: [U] (untyped) -> ::Array[U]? # - # Returns a new Array containing each element found in both `array` and Array - # `other_array`; duplicates are omitted; items are compared using `eql?` (items - # must also implement `hash` correctly): + # Returns a new array containing the *intersection* of `self` and `other_array`; + # that is, containing those elements found in both `self` and `other_array`: # # [0, 1, 2, 3] & [1, 2] # => [1, 2] - # [0, 1, 0, 1] & [0, 1] # => [0, 1] # - # Preserves order from `array`: + # Omits duplicates: + # + # [0, 1, 1, 0] & [0, 1] # => [0, 1] + # + # Preserves order from `self`: # # [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2] # - # Related: Array#intersection. + # Identifies common elements using method `#eql?` (as defined in each element of + # `self`). + # + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def &: (::Array[untyped] | _ToAry[untyped]) -> ::Array[Elem] # - # When non-negative argument Integer `n` is given, returns a new Array built by - # concatenating the `n` copies of `self`: + # When non-negative integer argument `n` is given, returns a new array built by + # concatenating `n` copies of `self`: # # a = ['x', 'y'] # a * 3 # => ["x", "y", "x", "y", "x", "y"] # - # When String argument `string_separator` is given, equivalent to - # `array.join(string_separator)`: + # When string argument `string_separator` is given, equivalent to + # `self.join(string_separator)`: # # [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}" # @@ -622,116 +684,145 @@ class Array[unchecked out Elem] < Object # - # Returns a new Array containing all elements of `array` followed by all - # elements of `other_array`: + # Returns a new array containing all elements of `self` followed by all elements + # of `other_array`: # # a = [0, 1] + [2, 3] # a # => [0, 1, 2, 3] # - # Related: #concat. + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def +: [U] (_ToAry[U]) -> ::Array[Elem | U] # - # Returns a new Array containing only those elements from `array` that are not - # found in Array `other_array`; items are compared using `eql?`; the order from - # `array` is preserved: + # Returns a new array containing only those elements of `self` that are not + # found in `other_array`; the order from `self` is preserved: + # + # [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] + # [0, 1, 1, 2, 1, 1, 3, 1, 1] - [3, 2, 0, :foo] # => [1, 1, 1, 1, 1, 1] + # [0, 1, 2] - [:foo] # => [0, 1, 2] # - # [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] - # [0, 1, 2, 3] - [3, 0] # => [1, 2] - # [0, 1, 2] - [4] # => [0, 1, 2] + # Element are compared using method `#eql?` (as defined in each element of + # `self`). # - # Related: Array#difference. + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def -: (_ToAry[untyped]) -> ::Array[Elem] # - # Appends `object` to `self`; returns `self`: + # Appends `object` as the last element in `self`; returns `self`: # - # a = [:foo, 'bar', 2] - # a << :baz # => [:foo, "bar", 2, :baz] + # [:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz] # - # Appends `object` as one element, even if it is another Array: + # Appends `object` as a single element, even if it is another array: # - # a = [:foo, 'bar', 2] - # a1 = a << [3, 4] - # a1 # => [:foo, "bar", 2, [3, 4]] + # [:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]] + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def <<: (Elem) -> self # - # Returns -1, 0, or 1 as `self` is less than, equal to, or greater than - # `other_array`. For each index `i` in `self`, evaluates `result = self[i] <=> - # other_array[i]`. + # Returns -1, 0, or 1 as `self` is determined to be less than, equal to, or + # greater than `other_array`. # - # Returns -1 if any result is -1: + # Iterates over each index `i` in `(0...self.size)`: # - # [0, 1, 2] <=> [0, 1, 3] # => -1 + # * Computes `result[i]` as `self[i] <=> other_array[i]`. + # * Immediately returns 1 if `result[i]` is 1: # - # Returns 1 if any result is 1: + # [0, 1, 2] <=> [0, 0, 2] # => 1 # - # [0, 1, 2] <=> [0, 1, 1] # => 1 + # * Immediately returns -1 if `result[i]` is -1: # - # When all results are zero: + # [0, 1, 2] <=> [0, 2, 2] # => -1 # - # * Returns -1 if `array` is smaller than `other_array`: + # * Continues if `result[i]` is 0. # - # [0, 1, 2] <=> [0, 1, 2, 3] # => -1 + # When every `result` is 0, returns `self.size <=> other_array.size` (see + # Integer#<=>): # - # * Returns 1 if `array` is larger than `other_array`: + # [0, 1, 2] <=> [0, 1] # => 1 + # [0, 1, 2] <=> [0, 1, 2] # => 0 + # [0, 1, 2] <=> [0, 1, 2, 3] # => -1 # - # [0, 1, 2] <=> [0, 1] # => 1 + # Note that when `other_array` is larger than `self`, its trailing elements do + # not affect the result: # - # * Returns 0 if `array` and `other_array` are the same size: + # [0, 1, 2] <=> [0, 1, 2, -3] # => -1 + # [0, 1, 2] <=> [0, 1, 2, 0] # => -1 + # [0, 1, 2] <=> [0, 1, 2, 3] # => -1 # - # [0, 1, 2] <=> [0, 1, 2] # => 0 + # Related: see [Methods for Comparing](rdoc-ref:Array@Methods+for+Comparing). # def <=>: (untyped) -> ::Integer? # - # Returns `true` if both `array.size == other_array.size` and for each index `i` - # in `array`, `array[i] == other_array[i]`: + # Returns whether both: # - # a0 = [:foo, 'bar', 2] - # a1 = [:foo, 'bar', 2.0] - # a1 == a0 # => true - # [] == [] # => true + # * `self` and `other_array` are the same size. + # * Their corresponding elements are the same; that is, for each index `i` in + # `(0...self.size)`, `self[i] == other_array[i]`. # - # Otherwise, returns `false`. + # Examples: + # + # [:foo, 'bar', 2] == [:foo, 'bar', 2] # => true + # [:foo, 'bar', 2] == [:foo, 'bar', 2.0] # => true + # [:foo, 'bar', 2] == [:foo, 'bar'] # => false # Different sizes. + # [:foo, 'bar', 2] == [:foo, 'bar', 3] # => false # Different elements. # # This method is different from method Array#eql?, which compares elements using # `Object#eql?`. # + # Related: see [Methods for Comparing](rdoc-ref:Array@Methods+for+Comparing). + # def ==: (untyped other) -> bool # # Returns elements from `self`; does not modify `self`. # - # When a single Integer argument `index` is given, returns the element at offset + # In brief: + # + # a = [:foo, 'bar', 2] + # + # # Single argument index: returns one element. + # a[0] # => :foo # Zero-based index. + # a[-1] # => 2 # Negative index counts backwards from end. + # + # # Arguments start and length: returns an array. + # a[1, 2] # => ["bar", 2] + # a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end. + # + # # Single argument range: returns an array. + # a[0..1] # => [:foo, "bar"] + # a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end. + # a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end. + # + # When a single integer argument `index` is given, returns the element at offset # `index`: # # a = [:foo, 'bar', 2] @@ -739,7 +830,7 @@ class Array[unchecked out Elem] < Object # a[2] # => 2 # a # => [:foo, "bar", 2] # - # If `index` is negative, counts relative to the end of `self`: + # If `index` is negative, counts backwards from the end of `self`: # # a = [:foo, 'bar', 2] # a[-1] # => 2 @@ -747,8 +838,9 @@ class Array[unchecked out Elem] < Object # # If `index` is out of range, returns `nil`. # - # When two Integer arguments `start` and `length` are given, returns a new Array - # of size `length` containing successive elements beginning at offset `start`: + # When two Integer arguments `start` and `length` are given, returns a new + # `Array` of size `length` containing successive elements beginning at offset + # `start`: # # a = [:foo, 'bar', 2] # a[0, 2] # => [:foo, "bar"] @@ -762,7 +854,7 @@ class Array[unchecked out Elem] < Object # a[1, 3] # => ["bar", 2] # a[2, 2] # => [2] # - # If `start == self.size` and `length >= 0`, returns a new empty Array. + # If `start == self.size` and `length >= 0`, returns a new empty `Array`. # # If `length` is negative, returns `nil`. # @@ -773,7 +865,7 @@ class Array[unchecked out Elem] < Object # a[0..1] # => [:foo, "bar"] # a[1..2] # => ["bar", 2] # - # Special case: If `range.start == a.size`, returns a new empty Array. + # Special case: If `range.start == a.size`, returns a new empty `Array`. # # If `range.end` is negative, calculates the end index from the end: # @@ -797,7 +889,7 @@ class Array[unchecked out Elem] < Object # a[4..-1] # => nil # # When a single Enumerator::ArithmeticSequence argument `aseq` is given, returns - # an Array of elements corresponding to the indexes produced by the sequence. + # an `Array` of elements corresponding to the indexes produced by the sequence. # # a = ['--', 'data1', '--', 'data2', '--', 'data3'] # a[(1..).step(2)] # => ["data1", "data2", "data3"] @@ -818,17 +910,47 @@ class Array[unchecked out Elem] < Object # # Raises TypeError (no implicit conversion of Symbol into Integer): # a[:foo] # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def []: %a{implicitly-returns-nil} (int index) -> Elem | (int start, int length) -> ::Array[Elem]? | (::Range[::Integer?] range) -> ::Array[Elem]? # - # Assigns elements in `self`; returns the given `object`. + # Assigns elements in `self`, based on the given `object`; returns `object`. + # + # In brief: + # + # a_orig = [:foo, 'bar', 2] + # + # # With argument index. + # a = a_orig.dup + # a[0] = 'foo' # => "foo" + # a # => ["foo", "bar", 2] + # a = a_orig.dup + # a[7] = 'foo' # => "foo" + # a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"] + # + # # With arguments start and length. + # a = a_orig.dup + # a[0, 2] = 'foo' # => "foo" + # a # => ["foo", 2] + # a = a_orig.dup + # a[6, 50] = 'foo' # => "foo" + # a # => [:foo, "bar", 2, nil, nil, nil, "foo"] + # + # # With argument range. + # a = a_orig.dup + # a[0..1] = 'foo' # => "foo" + # a # => ["foo", 2] + # a = a_orig.dup + # a[6..50] = 'foo' # => "foo" + # a # => [:foo, "bar", 2, nil, nil, nil, "foo"] # # When Integer argument `index` is given, assigns `object` to an element in # `self`. @@ -852,8 +974,8 @@ class Array[unchecked out Elem] < Object # a # => [:foo, "bar", "two"] # # When Integer arguments `start` and `length` are given and `object` is not an - # Array, removes `length - 1` elements beginning at offset `start`, and assigns - # `object` at offset `start`: + # `Array`, removes `length - 1` elements beginning at offset `start`, and + # assigns `object` at offset `start`: # # a = [:foo, 'bar', 2] # a[0, 2] = 'foo' # => "foo" @@ -886,9 +1008,9 @@ class Array[unchecked out Elem] < Object # a[1, 5] = 'foo' # => "foo" # a # => [:foo, "foo"] # - # When Range argument `range` is given and `object` is an Array, removes `length - # - 1` elements beginning at offset `start`, and assigns `object` at offset - # `start`: + # When Range argument `range` is given and `object` is not an `Array`, removes + # `length - 1` elements beginning at offset `start`, and assigns `object` at + # offset `start`: # # a = [:foo, 'bar', 2] # a[0..1] = 'foo' # => "foo" @@ -900,8 +1022,8 @@ class Array[unchecked out Elem] < Object # a[-2..2] = 'foo' # => "foo" # a # => [:foo, "foo"] # - # If the array length is less than `range.begin`, assigns `object` at offset - # `range.begin`, and ignores `length`: + # If the array length is less than `range.begin`, extends the array with `nil`, + # assigns `object` at offset `range.begin`, and ignores `length`: # # a = [:foo, 'bar', 2] # a[6..50] = 'foo' # => "foo" @@ -935,6 +1057,8 @@ class Array[unchecked out Elem] < Object # a[1..5] = 'foo' # => "foo" # a # => [:foo, "foo"] # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). + # def []=: (int index, Elem obj) -> Elem | (int start, int length, Elem obj) -> Elem | (int start, int length, ::Array[Elem]) -> ::Array[Elem] @@ -945,38 +1069,40 @@ class Array[unchecked out Elem] < Object # - # Returns `true` if all elements of `self` meet a given criterion. + # Returns whether for every element of `self`, a given criterion is satisfied. # - # If `self` has no element, returns `true` and argument or block are not used. + # With no block and no argument, returns whether every element of `self` is + # truthy: # - # With no block given and no argument, returns `true` if `self` contains only - # truthy elements, `false` otherwise: + # [[], {}, '', 0, 0.0, Object.new].all? # => true # All truthy objects. + # [[], {}, '', 0, 0.0, nil].all? # => false # nil is not truthy. + # [[], {}, '', 0, 0.0, false].all? # => false # false is not truthy. # - # [0, 1, :foo].all? # => true - # [0, nil, 2].all? # => false - # [].all? # => true + # With argument `object` given, returns whether `object === ele` for every + # element `ele` in `self`: # - # With a block given and no argument, calls the block with each element in - # `self`; returns `true` if the block returns only truthy values, `false` - # otherwise: + # [0, 0, 0].all?(0) # => true + # [0, 1, 2].all?(1) # => false + # ['food', 'fool', 'foot'].all?(/foo/) # => true + # ['food', 'drink'].all?(/foo/) # => false # - # [0, 1, 2].all? { |element| element < 3 } # => true - # [0, 1, 2].all? { |element| element < 2 } # => false + # With a block given, calls the block with each element in `self`; returns + # whether the block returns only truthy values: # - # If argument `obj` is given, returns `true` if `obj.===` every element, `false` - # otherwise: + # [0, 1, 2].all? { |ele| ele < 3 } # => true + # [0, 1, 2].all? { |ele| ele < 2 } # => false # - # ['food', 'fool', 'foot'].all?(/foo/) # => true - # ['food', 'drink'].all?(/bar/) # => false - # [].all?(/foo/) # => true - # [0, 0, 0].all?(0) # => true - # [0, 1, 2].all?(1) # => false + # With both a block and argument `object` given, ignores the block and uses + # `object` as above. # - # Related: Enumerable#all? + # **Special case**: returns `true` if `self` is empty (regardless of any given + # argument or block). + # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def all?: () -> bool | (_Pattern[Elem] pattern) -> bool @@ -984,275 +1110,303 @@ class Array[unchecked out Elem] < Object # - # Returns `true` if any element of `self` meets a given criterion. + # Returns whether for any element of `self`, a given criterion is satisfied. # - # If `self` has no element, returns `false` and argument or block are not used. + # With no block and no argument, returns whether any element of `self` is + # truthy: # - # With no block given and no argument, returns `true` if `self` has any truthy - # element, `false` otherwise: + # [nil, false, []].any? # => true # Array object is truthy. + # [nil, false, {}].any? # => true # Hash object is truthy. + # [nil, false, ''].any? # => true # String object is truthy. + # [nil, false].any? # => false # Nil and false are not truthy. # - # [nil, 0, false].any? # => true - # [nil, false].any? # => false - # [].any? # => false + # With argument `object` given, returns whether `object === ele` for any element + # `ele` in `self`: # - # With a block given and no argument, calls the block with each element in - # `self`; returns `true` if the block returns any truthy value, `false` - # otherwise: + # [nil, false, 0].any?(0) # => true + # [nil, false, 1].any?(0) # => false + # [nil, false, 'food'].any?(/foo/) # => true + # [nil, false, 'food'].any?(/bar/) # => false # - # [0, 1, 2].any? {|element| element > 1 } # => true - # [0, 1, 2].any? {|element| element > 2 } # => false + # With a block given, calls the block with each element in `self`; returns + # whether the block returns any truthy value: # - # If argument `obj` is given, returns `true` if `obj`.`===` any element, `false` - # otherwise: + # [0, 1, 2].any? {|ele| ele < 1 } # => true + # [0, 1, 2].any? {|ele| ele < 0 } # => false + # + # With both a block and argument `object` given, ignores the block and uses + # `object` as above. # - # ['food', 'drink'].any?(/foo/) # => true - # ['food', 'drink'].any?(/bar/) # => false - # [].any?(/foo/) # => false - # [0, 1, 2].any?(1) # => true - # [0, 1, 2].any?(3) # => false + # **Special case**: returns `false` if `self` is empty (regardless of any given + # argument or block). # - # Related: Enumerable#any? + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # alias any? all? # - # Appends trailing elements. + # Appends each argument in `objects` to `self`; returns `self`: # - # Appends each argument in `objects` to `self`; returns `self`: + # a = [:foo, 'bar', 2] # => [:foo, "bar", 2] + # a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] # - # a = [:foo, 'bar', 2] - # a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] - # - # Appends each argument as one element, even if it is another Array: + # Appends each argument as a single element, even if it is another array: # - # a = [:foo, 'bar', 2] - # a1 = a.push([:baz, :bat], [:bam, :bad]) - # a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] + # a = [:foo, 'bar', 2] # => [:foo, "bar", 2] + # a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] # - # Related: #pop, #shift, #unshift. + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # alias append push # - # Returns the first element in `self` that is an Array whose first element `==` - # `obj`: + # Returns the first element `ele` in `self` such that `ele` is an array and + # `ele[0] == object`: # # a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] # a.assoc(4) # => [4, 5, 6] # # Returns `nil` if no such element is found. # - # Related: #rassoc. + # Related: Array#rassoc; see also [Methods for + # Fetching](rdoc-ref:Array@Methods+for+Fetching). # def assoc: (untyped) -> ::Array[untyped]? # - # Returns the element at Integer offset `index`; does not modify `self`. + # Returns the element of `self` specified by the given `index` or `nil` if there + # is no such element; `index` must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). + # + # For non-negative `index`, returns the element of `self` at offset `index`: + # # a = [:foo, 'bar', 2] - # a.at(0) # => :foo - # a.at(2) # => 2 + # a.at(0) # => :foo + # a.at(2) # => 2 + # a.at(2.0) # => 2 + # + # For negative `index`, counts backwards from the end of `self`: + # + # a.at(-2) # => "bar" + # + # Related: Array#[]; see also [Methods for + # Fetching](rdoc-ref:Array@Methods+for+Fetching). # def at: %a{implicitly-returns-nil} (int index) -> Elem # - # Returns an element from `self` selected by a binary search. + # Returns the element from `self` found by a binary search, or `nil` if the + # search found no suitable element. # # See [Binary Searching](rdoc-ref:bsearch.rdoc). # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def bsearch: () -> ::Enumerator[Elem, Elem?] | () { (Elem) -> (true | false) } -> Elem? | () { (Elem) -> ::Integer } -> Elem? # - # Searches `self` as described at method #bsearch, but returns the *index* of - # the found element instead of the element itself. + # Returns the integer index of the element from `self` found by a binary search, + # or `nil` if the search found no suitable element. + # + # See [Binary Searching](rdoc-ref:bsearch.rdoc). + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def bsearch_index: () { (Elem) -> (true | false) } -> ::Integer? | () { (Elem) -> ::Integer } -> ::Integer? # - # Removes all elements from `self`: + # Removes all elements from `self`; returns `self`: # # a = [:foo, 'bar', 2] # a.clear # => [] # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). + # def clear: () -> self # - # Calls the block, if given, with each element of `self`; returns a new Array - # whose elements are the return values from the block: + # With a block given, calls the block with each element of `self`; returns a new + # array whose elements are the return values from the block: # # a = [:foo, 'bar', 2] # a1 = a.map {|element| element.class } # a1 # => [Symbol, String, Integer] # - # Returns a new Enumerator if no block given: - # a = [:foo, 'bar', 2] - # a1 = a.map - # a1 # => # + # With no block given, returns a new Enumerator. + # + # Related: #collect!; see also [Methods for + # Converting](rdoc-ref:Array@Methods+for+Converting). # def collect: [U] () { (Elem item) -> U } -> ::Array[U] | () -> ::Enumerator[Elem, ::Array[untyped]] # - # Calls the block, if given, with each element; replaces the element with the - # block's return value: + # With a block given, calls the block with each element of `self` and replaces + # the element with the block's return value; returns `self`: # # a = [:foo, 'bar', 2] # a.map! { |element| element.class } # => [Symbol, String, Integer] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # a1 = a.map! - # a1 # => # + # Related: #collect; see also [Methods for + # Converting](rdoc-ref:Array@Methods+for+Converting). # def collect!: () { (Elem item) -> Elem } -> self | () -> ::Enumerator[Elem, self] # - # Calls the block, if given, with combinations of elements of `self`; returns - # `self`. The order of combinations is indeterminate. - # - # When a block and an in-range positive Integer argument `n` (`0 < n <= - # self.size`) are given, calls the block with all `n`-tuple combinations of - # `self`. - # - # Example: + # When a block and a positive [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects) + # argument `n` (`0 < n <= self.size`) are given, calls the block with all + # `n`-tuple combinations of `self`; returns `self`: # - # a = [0, 1, 2] - # a.combination(2) {|combination| p combination } + # a = %w[a b c] # => ["a", "b", "c"] + # a.combination(2) {|combination| p combination } # => ["a", "b", "c"] # # Output: # - # [0, 1] - # [0, 2] - # [1, 2] - # - # Another example: - # - # a = [0, 1, 2] - # a.combination(3) {|combination| p combination } - # - # Output: + # ["a", "b"] + # ["a", "c"] + # ["b", "c"] # - # [0, 1, 2] + # The order of the yielded combinations is not guaranteed. # - # When `n` is zero, calls the block once with a new empty Array: + # When `n` is zero, calls the block once with a new empty array: # - # a = [0, 1, 2] - # a1 = a.combination(0) {|combination| p combination } + # a.combination(0) {|combination| p combination } + # [].combination(0) {|combination| p combination } # # Output: # # [] + # [] # - # When `n` is out of range (negative or larger than `self.size`), does not call - # the block: + # When `n` is negative or larger than `self.size` and `self` is non-empty, does + # not call the block: # - # a = [0, 1, 2] - # a.combination(-1) {|combination| fail 'Cannot happen' } - # a.combination(4) {|combination| fail 'Cannot happen' } + # a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] + # a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [0, 1, 2] - # a.combination(2) # => # + # Related: Array#permutation; see also [Methods for + # Iterating](rdoc-ref:Array@Methods+for+Iterating). # def combination: (int n) { (::Array[Elem]) -> void } -> self | (int n) -> ::Enumerator[::Array[Elem], self] # - # Returns a new Array containing all non-`nil` elements from `self`: + # Returns a new array containing only the non-`nil` elements from `self`; + # element order is preserved: # - # a = [nil, 0, nil, 1, nil, 2, nil] - # a.compact # => [0, 1, 2] + # a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] + # a.compact # => [0, false, "", [], {}] + # + # Related: Array#compact!; see also [Methods for + # Deleting](rdoc-ref:Array@Methods+for+Deleting). # def compact: () -> ::Array[Elem] # - # Removes all `nil` elements from `self`. + # Removes all `nil` elements from `self`; Returns `self` if any elements are + # removed, `nil` otherwise: + # + # a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] + # a.compact! # => [0, false, "", [], {}] + # a # => [0, false, "", [], {}] + # a.compact! # => nil # - # Returns `self` if any elements removed, otherwise `nil`. + # Related: Array#compact; see also [Methods for + # Deleting](rdoc-ref:Array@Methods+for+Deleting). # def compact!: () -> self? # - # Adds to `array` all elements from each Array in `other_arrays`; returns - # `self`: + # Adds to `self` all elements from each array in `other_arrays`; returns `self`: # # a = [0, 1] - # a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5] + # a.concat(['two', 'three'], [:four, :five], a) + # # => [0, 1, "two", "three", :four, :five, 0, 1] + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def concat: (*::Array[Elem] arrays) -> self # # Returns a count of specified elements. # # With no argument and no block, returns the count of all elements: # - # [0, 1, 2].count # => 3 - # [].count # => 0 + # [0, :one, 'two', 3, 3.0].count # => 5 # - # With argument `obj`, returns the count of elements `==` to `obj`: + # With argument `object` given, returns the count of elements `==` to `object`: # - # [0, 1, 2, 0.0].count(0) # => 2 - # [0, 1, 2].count(3) # => 0 + # [0, :one, 'two', 3, 3.0].count(3) # => 2 # # With no argument and a block given, calls the block with each element; returns # the count of elements for which the block returns a truthy value: # - # [0, 1, 2, 3].count {|element| element > 1} # => 2 + # [0, 1, 2, 3].count {|element| element > 1 } # => 2 # - # With argument `obj` and a block given, issues a warning, ignores the block, - # and returns the count of elements `==` to `obj`. + # With argument `object` and a block given, issues a warning, ignores the block, + # and returns the count of elements `==` to `object`. + # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def count: () -> ::Integer | (Elem obj) -> ::Integer @@ -1260,35 +1414,35 @@ class Array[unchecked out Elem] < Object # - # When called with positive Integer argument `count` and a block, calls the - # block with each element, then does so again, until it has done so `count` - # times; returns `nil`: + # With a block given, may call the block, depending on the value of argument + # `count`; `count` must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects), or + # `nil`. + # + # When `count` is positive, calls the block with each element, then does so + # repeatedly, until it has done so `count` times; returns `nil`: # # output = [] # [0, 1].cycle(2) {|element| output.push(element) } # => nil # output # => [0, 1, 0, 1] # - # If `count` is zero or negative, does not call the block: + # When `count` is zero or negative, does not call the block: # - # [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil + # [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil # [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil # - # When a block is given, and argument is omitted or `nil`, cycles forever: + # When `count` is `nil`, cycles forever: # # # Prints 0 and 1 forever. # [0, 1].cycle {|element| puts element } # [0, 1].cycle(nil) {|element| puts element } # - # When no block is given, returns a new Enumerator: + # With no block given, returns a new Enumerator. # - # [0, 1].cycle(2) # => # - # [0, 1].cycle # => # => # - # [0, 1].cycle.first(5) # => [0, 1, 0, 1, 0] + # Related: see [Methods for Iterating](rdoc-ref:Array@Methods+for+Iterating). # def cycle: (?int? n) { (Elem) -> void } -> nil | (?int? n) -> ::Enumerator[Elem, nil] @@ -1302,45 +1456,49 @@ class Array[unchecked out Elem] < Object # # Removes zero or more elements from `self`. # - # When no block is given, removes from `self` each element `ele` such that `ele - # == obj`; returns the last deleted element: + # With no block given, removes from `self` each element `ele` such that `ele == + # object`; returns the last removed element: # - # s1 = 'bar'; s2 = 'bar' - # a = [:foo, s1, 2, s2] - # a.delete('bar') # => "bar" - # a # => [:foo, 2] + # a = [0, 1, 2, 2.0] + # a.delete(2) # => 2.0 + # a # => [0, 1] # - # Returns `nil` if no elements removed. + # Returns `nil` if no elements removed: # - # When a block is given, removes from `self` each element `ele` such that `ele - # == obj`. + # a.delete(2) # => nil # - # If any such elements are found, ignores the block and returns the last deleted + # With a block given, removes from `self` each element `ele` such that `ele == + # object`. + # + # If any such elements are found, ignores the block and returns the last removed # element: # - # s1 = 'bar'; s2 = 'bar' - # a = [:foo, s1, 2, s2] - # deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' } - # a # => [:foo, 2] + # a = [0, 1, 2, 2.0] + # a.delete(2) {|element| fail 'Cannot happen' } # => 2.0 + # a # => [0, 1] # - # If no such elements are found, returns the block's return value: + # If no such element is found, returns the block's return value: # - # a = [:foo, 'bar', 2] - # a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found" + # a.delete(2) {|element| "Element #{element} not found." } + # # => "Element 2 not found." + # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def delete: (Elem obj) -> Elem? | [S, T] (S obj) { (S) -> T } -> (Elem | T) # - # Deletes an element from `self`, per the given Integer `index`. + # Removes the element of `self` at the given `index`, which must be an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). # # When `index` is non-negative, deletes the element at offset `index`: # @@ -1348,52 +1506,57 @@ class Array[unchecked out Elem] < Object # a.delete_at(1) # => "bar" # a # => [:foo, 2] # - # If index is too large, returns `nil`. - # # When `index` is negative, counts backward from the end of the array: # # a = [:foo, 'bar', 2] # a.delete_at(-2) # => "bar" # a # => [:foo, 2] # - # If `index` is too small (far from zero), returns nil. + # When `index` is out of range, returns `nil`. + # + # a = [:foo, 'bar', 2] + # a.delete_at(3) # => nil + # a.delete_at(-4) # => nil + # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def delete_at: %a{implicitly-returns-nil} (int index) -> Elem # - # Removes each element in `self` for which the block returns a truthy value; - # returns `self`: + # With a block given, calls the block with each element of `self`; removes the + # element if the block returns a truthy value; returns `self`: # # a = [:foo, 'bar', 2, 'bat'] # a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # a.delete_if # => # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def delete_if: () { (Elem item) -> boolish } -> self | () -> ::Enumerator[Elem, self] # - # Returns a new Array containing only those elements from `self` that are not - # found in any of the Arrays `other_arrays`; items are compared using `eql?`; + # Returns a new array containing only those elements from `self` that are not + # found in any of the given `other_arrays`; items are compared using `eql?`; # order from `self` is preserved: # # [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3] - # [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] - # [0, 1, 2].difference([4]) # => [0, 1, 2] + # [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] + # [0, 1, 2].difference([4]) # => [0, 1, 2] + # [0, 1, 2].difference # => [0, 1, 2] # - # Returns a copy of `self` if no arguments given. + # Returns a copy of `self` if no arguments are given. # - # Related: Array#-. + # Related: Array#-; see also [Methods for + # Combining](rdoc-ref:Array@Methods+for+Combining). # def difference: (*::Array[untyped] arrays) -> ::Array[Elem] @@ -1401,8 +1564,8 @@ class Array[unchecked out Elem] < Object # rdoc-file=array.c # - array.dig(index, *identifiers) -> object # --> - # Finds and returns the object in nested objects that is specified by `index` - # and `identifiers`. The nested objects may be instances of various classes. See + # Finds and returns the object in nested object specified by `index` and + # `identifiers`; the nested objects may be instances of various classes. See # [Dig Methods](rdoc-ref:dig_methods.rdoc). # # Examples: @@ -1413,14 +1576,16 @@ class Array[unchecked out Elem] < Object # a.dig(1, 2, 0) # => :bat # a.dig(1, 2, 3) # => nil # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def dig: (int idx) -> Elem? | (int idx, untyped, *untyped) -> untyped # - # Returns a new Array containing all but the first `n` element of `self`, where + # Returns a new array containing all but the first `n` element of `self`, where # `n` is a non-negative Integer; does not modify `self`. # # Examples: @@ -1429,40 +1594,39 @@ class Array[unchecked out Elem] < Object # a.drop(0) # => [0, 1, 2, 3, 4, 5] # a.drop(1) # => [1, 2, 3, 4, 5] # a.drop(2) # => [2, 3, 4, 5] + # a.drop(9) # => [] + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def drop: (int n) -> ::Array[Elem] # - # Returns a new Array containing zero or more trailing elements of `self`; does - # not modify `self`. - # # With a block given, calls the block with each successive element of `self`; - # stops if the block returns `false` or `nil`; returns a new Array *omitting* - # those elements for which the block returned a truthy value: + # stops if the block returns `false` or `nil`; returns a new array *omitting* + # those elements for which the block returned a truthy value; does not modify + # `self`: # # a = [0, 1, 2, 3, 4, 5] # a.drop_while {|element| element < 3 } # => [3, 4, 5] # - # With no block given, returns a new Enumerator: + # With no block given, returns a new Enumerator. # - # [0, 1].drop_while # => # => # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def drop_while: () { (Elem obj) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] # - # Iterates over array elements. - # - # When a block given, passes each successive array element to the block; returns - # `self`: + # With a block given, iterates over the elements of `self`, passing each element + # to the block; returns `self`: # # a = [:foo, 'bar', 2] # a.each {|element| puts "#{element.class} #{element}" } @@ -1483,33 +1647,20 @@ class Array[unchecked out Elem] < Object # foo # bar # - # When no block given, returns a new Enumerator: - # a = [:foo, 'bar', 2] - # - # e = a.each - # e # => # - # a1 = e.each {|element| puts "#{element.class} #{element}" } - # - # Output: - # - # Symbol foo - # String bar - # Integer 2 + # With no block given, returns a new Enumerator. # - # Related: #each_index, #reverse_each. + # Related: see [Methods for Iterating](rdoc-ref:Array@Methods+for+Iterating). # def each: () -> ::Enumerator[Elem, self] | () { (Elem item) -> void } -> self # - # Iterates over array indexes. - # - # When a block given, passes each successive array index to the block; returns - # `self`: + # With a block given, iterates over the elements of `self`, passing each *array + # index* to the block; returns `self`: # # a = [:foo, 'bar', 2] # a.each_index {|index| puts "#{index} #{a[index]}" } @@ -1524,26 +1675,16 @@ class Array[unchecked out Elem] < Object # # a = [:foo, 'bar', 2] # a.each_index {|index| puts index; a.clear if index > 0 } + # a # => [] # # Output: # # 0 # 1 # - # When no block given, returns a new Enumerator: - # - # a = [:foo, 'bar', 2] - # e = a.each_index - # e # => # - # a1 = e.each {|index| puts "#{index} #{a[index]}"} - # - # Output: - # - # 0 foo - # 1 bar - # 2 2 + # With no block given, returns a new Enumerator. # - # Related: #each, #reverse_each. + # Related: see [Methods for Iterating](rdoc-ref:Array@Methods+for+Iterating). # def each_index: () { (::Integer index) -> void } -> self | () -> ::Enumerator[::Integer, self] @@ -1554,14 +1695,16 @@ class Array[unchecked out Elem] < Object # --> # Returns `true` if the count of elements in `self` is zero, `false` otherwise. # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). + # def empty?: () -> bool # # Returns `true` if `self` and `other_array` are the same size, and if, for each - # index `i` in `self`, `self[i].eql? other_array[i]`: + # index `i` in `self`, `self[i].eql?(other_array[i])`: # # a0 = [:foo, 'bar', 2] # a1 = [:foo, 'bar', 2] @@ -1572,21 +1715,26 @@ class Array[unchecked out Elem] < Object # This method is different from method Array#==, which compares using method # `Object#==`. # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). + # def eql?: (untyped other) -> bool # - # Returns the element at offset `index`. + # Returns the element of `self` at offset `index` if `index` is in range; + # `index` must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). # - # With the single Integer argument `index`, returns the element at offset + # With the single argument `index` and no block, returns the element at offset # `index`: # # a = [:foo, 'bar', 2] - # a.fetch(1) # => "bar" + # a.fetch(1) # => "bar" + # a.fetch(1.1) # => "bar" # # If `index` is negative, counts from the end of the array: # @@ -1594,11 +1742,12 @@ class Array[unchecked out Elem] < Object # a.fetch(-1) # => 2 # a.fetch(-2) # => "bar" # - # With arguments `index` and `default_value`, returns the element at offset - # `index` if index is in range, otherwise returns `default_value`: + # With arguments `index` and `default_value` (which may be any object) and no + # block, returns `default_value` if `index` is out-of-range: # # a = [:foo, 'bar', 2] - # a.fetch(1, nil) # => "bar" + # a.fetch(1, nil) # => "bar" + # a.fetch(3, :foo) # => :foo # # With argument `index` and a block, returns the element at offset `index` if # index is in range (and the block is not called); otherwise calls the block @@ -1608,206 +1757,189 @@ class Array[unchecked out Elem] < Object # a.fetch(1) {|index| raise 'Cannot happen' } # => "bar" # a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50" # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def fetch: (int index) -> Elem | [T] (int index, T default) -> (Elem | T) | [T] (int index) { (int index) -> T } -> (Elem | T) # - # Replaces specified elements in `self` with specified objects; returns `self`. - # - # With argument `obj` and no block given, replaces all elements with that one - # object: - # - # a = ['a', 'b', 'c', 'd'] - # a # => ["a", "b", "c", "d"] - # a.fill(:X) # => [:X, :X, :X, :X] - # - # With arguments `obj` and Integer `start`, and no block given, replaces - # elements based on the given start. - # - # If `start` is in range (`0 <= start < array.size`), replaces all elements from - # offset `start` through the end: - # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 2) # => ["a", "b", :X, :X] + # Replaces selected elements in `self`; may add elements to `self`; always + # returns `self` (never a new array). # - # If `start` is too large (`start >= array.size`), does nothing: + # In brief: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 4) # => ["a", "b", "c", "d"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 5) # => ["a", "b", "c", "d"] + # # Non-negative start. + # ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] # - # If `start` is negative, counts from the end (starting index is `start + - # array.size`): + # # Extends with specified values if necessary. + # ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] + # ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, -2) # => ["a", "b", :X, :X] + # # Fills with nils if necessary. + # ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] + # ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"] # - # If `start` is too small (less than and far from zero), replaces all elements: + # # For negative start, counts backwards from the end. + # ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] + # ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, -6) # => [:X, :X, :X, :X] - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, -50) # => [:X, :X, :X, :X] + # # Range. + # ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"] # - # With arguments `obj`, Integer `start`, and Integer `length`, and no block - # given, replaces elements based on the given `start` and `length`. + # When arguments `start` and `count` are given, they select the elements of + # `self` to be replaced; each must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects) (or + # `nil`): # - # If `start` is in range, replaces `length` elements beginning at offset - # `start`: + # * `start` specifies the zero-based offset of the first element to be + # replaced; `nil` means zero. + # * `count` is the number of consecutive elements to be replaced; `nil` means + # "all the rest." # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 1, 1) # => ["a", :X, "c", "d"] + # With argument `object` given, that one object is used for all replacements: # - # If `start` is negative, counts from the end: + # o = Object.new # => # + # a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] + # a.fill(o, 1, 2) + # # => ["a", #, #, "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, -2, 1) # => ["a", "b", :X, "d"] + # With a block given, the block is called once for each element to be replaced; + # the value passed to the block is the *index* of the element to be replaced + # (not the element itself); the block's return value replaces the element: # - # If `start` is large (`start >= array.size`), extends `self` with `nil`: + # a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] + # a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil] - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X] + # For arguments `start` and `count`: # - # If `length` is zero or negative, replaces no elements: + # * If `start` is non-negative, replaces `count` elements beginning at offset + # `start`: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, 1, 0) # => ["a", "b", "c", "d"] - # a.fill(:X, 1, -1) # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 0, 2) # => ["-", "-", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 2, 2) # => ["a", "b", "-", "-"] # - # With arguments `obj` and Range `range`, and no block given, replaces elements - # based on the given range. + # ['a', 'b', 'c', 'd'].fill(0, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] + # ['a', 'b', 'c', 'd'].fill(2, 2) {|e| e.to_s } # => ["a", "b", "2", "3"] # - # If the range is positive and ascending (`0 < range.begin <= range.end`), - # replaces elements from `range.begin` to `range.end`: + # Extends `self` if necessary: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (1..1)) # => ["a", :X, "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] + # ['a', 'b', 'c', 'd'].fill('-', 4, 2) # => ["a", "b", "c", "d", "-", "-"] # - # If `range.first` is negative, replaces no elements: + # ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] + # ['a', 'b', 'c', 'd'].fill(4, 2) {|e| e.to_s } # => ["a", "b", "c", "d", "4", "5"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"] + # Fills with `nil` if necessary: # - # If `range.last` is negative, counts from the end: + # ['a', 'b', 'c', 'd'].fill('-', 5, 2) # => ["a", "b", "c", "d", nil, "-", "-"] + # ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"] + # ['a', 'b', 'c', 'd'].fill(5, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, "5", "6"] + # ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"] # - # If `range.last` and `range.last` are both negative, both count from the end of - # the array: + # Does nothing if `count` is non-positive: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X] - # a = ['a', 'b', 'c', 'd'] - # a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"] + # ['a', 'b', 'c', 'd'].fill('-', 2, 0) # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 2, -100) # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 6, -100) # => ["a", "b", "c", "d"] # - # With no arguments and a block given, calls the block with each index; replaces - # the corresponding element with the block's return value: + # ['a', 'b', 'c', 'd'].fill(2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(2, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(6, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] + # * If `start` is negative, counts backwards from the end of `self`: # - # With argument `start` and a block given, calls the block with each index from - # offset `start` to the end; replaces the corresponding element with the block's - # return value. + # ['a', 'b', 'c', 'd'].fill('-', -4, 3) # => ["-", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] # - # If start is in range (`0 <= start < array.size`), replaces from offset `start` - # to the end: + # ['a', 'b', 'c', 'd'].fill(-4, 3) {|e| e.to_s } # => ["0", "1", "2", "d"] + # ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"] + # Extends `self` if necessary: # - # If `start` is too large(`start >= array.size`), does nothing: + # ['a', 'b', 'c', 'd'].fill('-', -2, 3) # => ["a", "b", "-", "-", "-"] + # ['a', 'b', 'c', 'd'].fill('-', -1, 3) # => ["a", "b", "c", "-", "-", "-"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(-2, 3) {|e| e.to_s } # => ["a", "b", "2", "3", "4"] + # ['a', 'b', 'c', 'd'].fill(-1, 3) {|e| e.to_s } # => ["a", "b", "c", "3", "4", "5"] # - # If `start` is negative, counts from the end: + # Starts at the beginning of `self` if `start` is negative and out-of-range: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"] + # ['a', 'b', 'c', 'd'].fill('-', -5, 2) # => ["-", "-", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', -6, 2) # => ["-", "-", "c", "d"] # - # If start is too small (`start <= -array.size`, replaces all elements: + # ['a', 'b', 'c', 'd'].fill(-5, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(-6, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] + # Does nothing if `count` is non-positive: # - # With arguments `start` and `length`, and a block given, calls the block for - # each index specified by start length; replaces the corresponding element with - # the block's return value. + # ['a', 'b', 'c', 'd'].fill('-', -2, 0) # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', -2, -1) # => ["a", "b", "c", "d"] # - # If `start` is in range, replaces `length` elements beginning at offset - # `start`: + # ['a', 'b', 'c', 'd'].fill(-2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(-2, -1) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"] + # When argument `range` is given, it must be a Range object whose members are + # numeric; its `begin` and `end` values determine the elements of `self` to be + # replaced: # - # If start is negative, counts from the end: + # * If both `begin` and `end` are positive, they specify the first and last + # elements to be replaced: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"] # - # If `start` is large (`start >= array.size`), extends `self` with `nil`: + # If `end` is smaller than `begin`, replaces no elements: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil] - # a = ['a', 'b', 'c', 'd'] - # a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"] + # ['a', 'b', 'c', 'd'].fill('-', 2..1) # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(2..1) {|e| e.to_s } # => ["a", "b", "c", "d"] # - # If `length` is zero or less, replaces no elements: + # * If either is negative (or both are negative), counts backwards from the + # end of `self`: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"] - # a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', -3..2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 1..-2) # => ["a", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill('-', -3..-2) # => ["a", "-", "-", "d"] # - # With arguments `obj` and `range`, and a block given, calls the block with each - # index in the given range; replaces the corresponding element with the block's - # return value. + # ['a', 'b', 'c', 'd'].fill(-3..2) {|e| e.to_s } # => ["a", "1", "2", "d"] + # ['a', 'b', 'c', 'd'].fill(1..-2) {|e| e.to_s } # => ["a", "1", "2", "d"] + # ['a', 'b', 'c', 'd'].fill(-3..-2) {|e| e.to_s } # => ["a", "1", "2", "d"] # - # If the range is positive and ascending (`range 0 < range.begin <= range.end`, - # replaces elements from `range.begin` to `range.end`: + # * If the `end` value is excluded (see Range#exclude_end?), omits the last + # replacement: # - # a = ['a', 'b', 'c', 'd'] - # a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 1...2) # => ["a", "-", "c", "d"] + # ['a', 'b', 'c', 'd'].fill('-', 1...-2) # => ["a", "-", "c", "d"] # - # If `range.first` is negative, does nothing: + # ['a', 'b', 'c', 'd'].fill(1...2) {|e| e.to_s } # => ["a", "1", "c", "d"] + # ['a', 'b', 'c', 'd'].fill(1...-2) {|e| e.to_s } # => ["a", "1", "c", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + # * If the range is endless (see [Endless + # Ranges](rdoc-ref:Range@Endless+Ranges)), replaces elements to the end of + # `self`: # - # If `range.last` is negative, counts from the end: + # ['a', 'b', 'c', 'd'].fill('-', 1..) # => ["a", "-", "-", "-"] + # ['a', 'b', 'c', 'd'].fill(1..) {|e| e.to_s } # => ["a", "1", "2", "3"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"] + # * If the range is beginless (see [Beginless + # Ranges](rdoc-ref:Range@Beginless+Ranges)), replaces elements from the + # beginning of `self`: # - # If `range.first` and `range.last` are both negative, both count from the end: + # ['a', 'b', 'c', 'd'].fill('-', ..2) # => ["-", "-", "-", "d"] + # ['a', 'b', 'c', 'd'].fill(..2) {|e| e.to_s } # => ["0", "1", "2", "d"] # - # a = ['a', 'b', 'c', 'd'] - # a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"] - # a = ['a', 'b', 'c', 'd'] - # a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"] + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def fill: (Elem obj) -> self | (Elem obj, int? start, ?int? length) -> self @@ -1816,25 +1948,24 @@ class Array[unchecked out Elem] < Object | (::Range[::Integer] range) { (::Integer index) -> Elem } -> self # - # Calls the block, if given, with each element of `self`; returns a new Array - # containing those elements of `self` for which the block returns a truthy + # With a block given, calls the block with each element of `self`; returns a new + # array containing those elements of `self` for which the block returns a truthy # value: # # a = [:foo, 'bar', 2, :bam] - # a1 = a.select {|element| element.to_s.start_with?('b') } - # a1 # => ["bar", :bam] + # a.select {|element| element.to_s.start_with?('b') } + # # => ["bar", :bam] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, :bam] - # a.select # => # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def filter: () { (Elem item) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] # - # Calls the block, if given with each element of `self`; removes from `self` - # those elements for which the block returns `false` or `nil`. + # With a block given, calls the block with each element of `self`; removes from + # `self` those elements for which the block returns `false` or `nil`. # # Returns `self` if any elements were removed: # @@ -1843,47 +1974,43 @@ class Array[unchecked out Elem] < Object # # Returns `nil` if no elements were removed. # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, :bam] - # a.select! # => # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def filter!: () { (Elem item) -> boolish } -> self? | () -> ::Enumerator[Elem, self?] # - # Returns the index of a specified element. + # Returns the zero-based integer index of a specified element, or `nil`. # - # When argument `object` is given but no block, returns the index of the first - # element `element` for which `object == element`: + # With only argument `object` given, returns the index of the first element + # `element` for which `object == element`: # # a = [:foo, 'bar', 2, 'bar'] # a.index('bar') # => 1 # # Returns `nil` if no such element found. # - # When both argument `object` and a block are given, calls the block with each - # successive element; returns the index of the first element for which the block - # returns a truthy value: + # With only a block given, calls the block with each successive element; returns + # the index of the first element for which the block returns a truthy value: # # a = [:foo, 'bar', 2, 'bar'] # a.index {|element| element == 'bar' } # => 1 # # Returns `nil` if the block never returns a truthy value. # - # When neither an argument nor a block is given, returns a new Enumerator: + # With neither an argument nor a block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # e = a.index - # e # => # - # e.each {|element| element == 'bar' } # => 1 - # - # Related: #rindex. + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def find_index: (untyped obj) -> ::Integer? | () { (Elem item) -> boolish } -> ::Integer? @@ -1891,12 +2018,12 @@ class Array[unchecked out Elem] < Object # - # Returns elements from `self`; does not modify `self`. + # Returns elements from `self`, or `nil`; does not modify `self`. # - # When no argument is given, returns the first element: + # With no argument given, returns the first element (if available): # # a = [:foo, 'bar', 2] # a.first # => :foo @@ -1904,399 +2031,399 @@ class Array[unchecked out Elem] < Object # # If `self` is empty, returns `nil`. # - # When non-negative Integer argument `n` is given, returns the first `n` - # elements in a new Array: - # - # a = [:foo, 'bar', 2] - # a.first(2) # => [:foo, "bar"] + # [].first # => nil # - # If `n >= array.size`, returns all elements: + # With non-negative integer argument `count` given, returns the first `count` + # elements (as available) in a new array: # - # a = [:foo, 'bar', 2] + # a.first(0) # => [] + # a.first(2) # => [:foo, "bar"] # a.first(50) # => [:foo, "bar", 2] # - # If `n == 0` returns an new empty Array: - # - # a = [:foo, 'bar', 2] - # a.first(0) # [] - # - # Related: #last. + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def first: %a{implicitly-returns-nil} () -> Elem | (int n) -> ::Array[Elem] # - # Returns a new Array that is a recursive flattening of `self`: - # * Each non-Array element is unchanged. - # * Each Array is replaced by its individual elements. + # Returns a new array that is a recursive flattening of `self` to `depth` levels + # of recursion; `depth` must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects) or + # `nil`. At each level of recursion: + # + # * Each element that is an array is "flattened" (that is, replaced by its + # individual array elements). + # * Each element that is not an array is unchanged (even if the element is an + # object that has instance method `flatten`). # - # With non-negative Integer argument `level`, flattens recursively through - # `level` levels: + # With non-negative integer argument `depth`, flattens recursively through + # `depth` levels: # - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(0) # => [0, [1, [2, 3], 4], 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(1) # => [0, 1, [2, 3], 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(2) # => [0, 1, 2, 3, 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(3) # => [0, 1, 2, 3, 4, 5] + # a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] + # a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #] + # a.flatten(0) # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #] + # a.flatten(1 ) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #] + # a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #] + # a.flatten(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # a.flatten(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] # - # With no argument, a `nil` argument, or with negative argument `level`, - # flattens all levels: + # With `nil` or negative `depth`, flattens all levels. # - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten # => [0, 1, 2, 3, 4, 5] - # [0, 1, 2].flatten # => [0, 1, 2] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(-1) # => [0, 1, 2, 3, 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten(-2) # => [0, 1, 2, 3, 4, 5] - # [0, 1, 2].flatten(-1) # => [0, 1, 2] + # a.flatten # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # + # Related: Array#flatten!; see also [Methods for + # Converting](rdoc-ref:Array@Methods+for+Converting). # def flatten: (?int level) -> ::Array[untyped] # - # Replaces each nested Array in `self` with the elements from that Array; - # returns `self` if any changes, `nil` otherwise. + # Returns `self` as a recursively flattening of `self` to `depth` levels of + # recursion; `depth` must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects), or + # `nil`. At each level of recursion: + # + # * Each element that is an array is "flattened" (that is, replaced by its + # individual array elements). + # * Each element that is not an array is unchanged (even if the element is an + # object that has instance method `flatten`). # - # With non-negative Integer argument `level`, flattens recursively through - # `level` levels: + # Returns `nil` if no elements were flattened. # - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten!(1) # => [0, 1, [2, 3], 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten!(2) # => [0, 1, 2, 3, 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten!(3) # => [0, 1, 2, 3, 4, 5] - # [0, 1, 2].flatten!(1) # => nil + # With non-negative integer argument `depth`, flattens recursively through + # `depth` levels: # - # With no argument, a `nil` argument, or with negative argument `level`, - # flattens all levels: + # a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] + # a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #] + # a.dup.flatten!(1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #] + # a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #] + # a.dup.flatten!(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # a.dup.flatten!(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] # - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten! # => [0, 1, 2, 3, 4, 5] - # [0, 1, 2].flatten! # => nil - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten!(-1) # => [0, 1, 2, 3, 4, 5] - # a = [ 0, [ 1, [2, 3], 4 ], 5 ] - # a.flatten!(-2) # => [0, 1, 2, 3, 4, 5] - # [0, 1, 2].flatten!(-1) # => nil + # With `nil` or negative argument `depth`, flattens all levels: + # + # a.dup.flatten! # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #] + # + # Related: Array#flatten; see also [Methods for + # Assigning](rdoc-ref:Array@Methods+for+Assigning). # def flatten!: (?int level) -> self? # # Returns the integer hash value for `self`. # - # Two arrays with the same content will have the same hash code (and will + # Two arrays with the same content will have the same hash value (and will # compare using eql?): # - # [0, 1, 2].hash == [0, 1, 2].hash # => true - # [0, 1, 2].hash == [0, 1, 3].hash # => false + # ['a', 'b'].hash == ['a', 'b'].hash # => true + # ['a', 'b'].hash == ['a', 'c'].hash # => false + # ['a', 'b'].hash == ['a'].hash # => false # def hash: () -> ::Integer # - # Returns `true` if for some index `i` in `self`, `obj == self[i]`; otherwise - # `false`: + # Returns whether for some element `element` in `self`, `object == element`: + # + # [0, 1, 2].include?(2) # => true + # [0, 1, 2].include?(2.0) # => true + # [0, 1, 2].include?(2.1) # => false # - # [0, 1, 2].include?(2) # => true - # [0, 1, 2].include?(3) # => false + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def include?: (Elem object) -> bool # - # Returns the index of a specified element. + # Returns the zero-based integer index of a specified element, or `nil`. # - # When argument `object` is given but no block, returns the index of the first - # element `element` for which `object == element`: + # With only argument `object` given, returns the index of the first element + # `element` for which `object == element`: # # a = [:foo, 'bar', 2, 'bar'] # a.index('bar') # => 1 # # Returns `nil` if no such element found. # - # When both argument `object` and a block are given, calls the block with each - # successive element; returns the index of the first element for which the block - # returns a truthy value: + # With only a block given, calls the block with each successive element; returns + # the index of the first element for which the block returns a truthy value: # # a = [:foo, 'bar', 2, 'bar'] # a.index {|element| element == 'bar' } # => 1 # # Returns `nil` if the block never returns a truthy value. # - # When neither an argument nor a block is given, returns a new Enumerator: - # - # a = [:foo, 'bar', 2] - # e = a.index - # e # => # - # e.each {|element| element == 'bar' } # => 1 + # With neither an argument nor a block given, returns a new Enumerator. # - # Related: #rindex. + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # alias index find_index # - # Inserts given `objects` before or after the element at Integer index `offset`; - # returns `self`. + # Inserts the given `objects` as elements of `self`; returns `self`. # - # When `index` is non-negative, inserts all given `objects` before the element - # at offset `index`: + # When `index` is non-negative, inserts `objects` *before* the element at offset + # `index`: # - # a = [:foo, 'bar', 2] - # a.insert(1, :bat, :bam) # => [:foo, :bat, :bam, "bar", 2] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.insert(1, :x, :y, :z) # => ["a", :x, :y, :z, "b", "c"] # # Extends the array if `index` is beyond the array (`index >= self.size`): # - # a = [:foo, 'bar', 2] - # a.insert(5, :bat, :bam) - # a # => [:foo, "bar", 2, nil, nil, :bat, :bam] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z] # - # Does nothing if no objects given: + # When `index` is negative, inserts `objects` *after* the element at offset + # `index + self.size`: # - # a = [:foo, 'bar', 2] - # a.insert(1) - # a.insert(50) - # a.insert(-50) - # a # => [:foo, "bar", 2] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"] # - # When `index` is negative, inserts all given `objects` *after* the element at - # offset `index+self.size`: + # With no `objects` given, does nothing: # - # a = [:foo, 'bar', 2] - # a.insert(-2, :bat, :bam) - # a # => [:foo, "bar", :bat, :bam, 2] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.insert(1) # => ["a", "b", "c"] + # a.insert(50) # => ["a", "b", "c"] + # a.insert(-50) # => ["a", "b", "c"] + # + # Raises IndexError if `objects` are given and `index` is negative and out of + # range. + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def insert: (int index, *Elem obj) -> self # - # Returns the new String formed by calling method `#inspect` on each array + # Returns the new string formed by calling method `#inspect` on each array # element: # # a = [:foo, 'bar', 2] # a.inspect # => "[:foo, \"bar\", 2]" # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). + # def inspect: () -> String # - # Returns `true` if the array and `other_ary` have at least one element in - # common, otherwise returns `false`: + # Returns whether `other_array` has at least one element that is `#eql?` to some + # element of `self`: + # + # [1, 2, 3].intersect?([3, 4, 5]) # => true + # [1, 2, 3].intersect?([4, 5, 6]) # => false # - # a = [ 1, 2, 3 ] - # b = [ 3, 4, 5 ] - # c = [ 5, 6, 7 ] - # a.intersect?(b) #=> true - # a.intersect?(c) #=> false + # Each element must correctly implement method `#hash`. # - # Array elements are compared using `eql?` (items must also implement `hash` - # correctly). + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def intersect?: (_ToAry[untyped]) -> bool # - # Returns a new Array containing each element found both in `self` and in all of - # the given Arrays `other_arrays`; duplicates are omitted; items are compared - # using `eql?` (items must also implement `hash` correctly): + # Returns a new array containing each element in `self` that is `#eql?` to at + # least one element in each of the given `other_arrays`; duplicates are omitted: # - # [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] # [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] # - # Preserves order from `self`: + # Each element must correctly implement method `#hash`. + # + # Order from `self` is preserved: # # [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2] # - # Returns a copy of `self` if no arguments given. + # Returns a copy of `self` if no arguments are given. # - # Related: Array#&. + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def intersection: (*::Array[untyped] | _ToAry[untyped] other_ary) -> ::Array[Elem] # - # Returns the new String formed by joining the array elements after conversion. - # For each element `element`: + # Returns the new string formed by joining the converted elements of `self`; for + # each element `element`: # - # * Uses `element.to_s` if `element` is not a `kind_of?(Array)`. - # * Uses recursive `element.join(separator)` if `element` is a + # * Converts recursively using `element.join(separator)` if `element` is a # `kind_of?(Array)`. + # * Otherwise, converts using `element.to_s`. # - # With no argument, joins using the output field separator, `$,`: + # With no argument given, joins using the output field separator, `$,`: # # a = [:foo, 'bar', 2] # $, # => nil # a.join # => "foobar2" # - # With string argument `separator`, joins using that separator: + # With string argument `separator` given, joins using that separator: # # a = [:foo, 'bar', 2] # a.join("\n") # => "foo\nbar\n2" # - # Joins recursively for nested Arrays: + # Joins recursively for nested arrays: # # a = [:foo, [:bar, [:baz, :bat]]] # a.join # => "foobarbazbat" # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). + # def join: (?string separator) -> String # - # Retains those elements for which the block returns a truthy value; deletes all - # other elements; returns `self`: + # With a block given, calls the block with each element of `self`; removes the + # element from `self` if the block does not return a truthy value: # # a = [:foo, 'bar', 2, :bam] # a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, :bam] - # a.keep_if # => # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def keep_if: () { (Elem item) -> boolish } -> self | () -> ::Enumerator[Elem, self] # - # Returns elements from `self`; `self` is not modified. + # Returns elements from `self`, or `nil`; `self` is not modified. # - # When no argument is given, returns the last element: + # With no argument given, returns the last element, or `nil` if `self` is empty: # # a = [:foo, 'bar', 2] # a.last # => 2 # a # => [:foo, "bar", 2] + # [].last # => nil # - # If `self` is empty, returns `nil`. - # - # When non-negative Integer argument `n` is given, returns the last `n` elements - # in a new Array: - # - # a = [:foo, 'bar', 2] - # a.last(2) # => ["bar", 2] - # - # If `n >= array.size`, returns all elements: + # With non-negative integer argument `n` is given, returns a new array + # containing the trailing `n` elements of `self`, as available: # # a = [:foo, 'bar', 2] + # a.last(2) # => ["bar", 2] # a.last(50) # => [:foo, "bar", 2] + # a.last(0) # => [] + # [].last(3) # => [] # - # If `n == 0`, returns an new empty Array: - # - # a = [:foo, 'bar', 2] - # a.last(0) # [] - # - # Related: #first. + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def last: %a{implicitly-returns-nil} () -> Elem | (int n) -> ::Array[Elem] # - # Returns the count of elements in `self`. + # Returns the count of elements in `self`: + # + # [0, 1, 2].length # => 3 + # [].length # => 0 + # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def length: () -> ::Integer # - # Calls the block, if given, with each element of `self`; returns a new Array - # whose elements are the return values from the block: + # With a block given, calls the block with each element of `self`; returns a new + # array whose elements are the return values from the block: # # a = [:foo, 'bar', 2] # a1 = a.map {|element| element.class } # a1 # => [Symbol, String, Integer] # - # Returns a new Enumerator if no block given: - # a = [:foo, 'bar', 2] - # a1 = a.map - # a1 # => # + # With no block given, returns a new Enumerator. + # + # Related: #collect!; see also [Methods for + # Converting](rdoc-ref:Array@Methods+for+Converting). # alias map collect # - # Calls the block, if given, with each element; replaces the element with the - # block's return value: + # With a block given, calls the block with each element of `self` and replaces + # the element with the block's return value; returns `self`: # # a = [:foo, 'bar', 2] # a.map! { |element| element.class } # => [Symbol, String, Integer] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # a1 = a.map! - # a1 # => # + # Related: #collect; see also [Methods for + # Converting](rdoc-ref:Array@Methods+for+Converting). # alias map! collect! # # Returns one of the following: # # * The maximum-valued element from `self`. - # * A new Array of maximum-valued elements selected from `self`. + # * A new array of maximum-valued elements from `self`. + # + # Does not modify `self`. # - # When no block is given, each element in `self` must respond to method `<=>` - # with an Integer. + # With no block given, each element in `self` must respond to method `#<=>` with + # a numeric. # # With no argument and no block, returns the element in `self` having the - # maximum value per method `<=>`: + # maximum value per method `#<=>`: # - # [0, 1, 2].max # => 2 + # [1, 0, 3, 2].max # => 3 # - # With an argument Integer `n` and no block, returns a new Array with at most - # `n` elements, in descending order per method `<=>`: + # With non-negative numeric argument `n` and no block, returns a new array with + # at most `n` elements, in descending order, per method `#<=>`: # - # [0, 1, 2, 3].max(3) # => [3, 2, 1] - # [0, 1, 2, 3].max(6) # => [3, 2, 1, 0] + # [1, 0, 3, 2].max(3) # => [3, 2, 1] + # [1, 0, 3, 2].max(3.0) # => [3, 2, 1] + # [1, 0, 3, 2].max(9) # => [3, 2, 1, 0] + # [1, 0, 3, 2].max(0) # => [] # - # When a block is given, the block must return an Integer. + # With a block given, the block must return a numeric. # - # With a block and no argument, calls the block `self.size-1` times to compare + # With a block and no argument, calls the block `self.size - 1` times to compare # elements; returns the element having the maximum value per the block: # - # ['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000" + # ['0', '', '000', '00'].max {|a, b| a.size <=> b.size } + # # => "000" # - # With an argument `n` and a block, returns a new Array with at most `n` - # elements, in descending order per the block: + # With non-negative numeric argument `n` and a block, returns a new array with + # at most `n` elements, in descending order, per the block: # - # ['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"] + # ['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size } + # # => ["000", "00"] + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def max: %a{implicitly-returns-nil} () -> Elem | %a{implicitly-returns-nil} () { (Elem a, Elem b) -> ::Integer? } -> Elem @@ -2305,107 +2432,117 @@ class Array[unchecked out Elem] < Object # # Returns one of the following: # # * The minimum-valued element from `self`. - # * A new Array of minimum-valued elements selected from `self`. + # * A new array of minimum-valued elements from `self`. + # + # Does not modify `self`. # - # When no block is given, each element in `self` must respond to method `<=>` - # with an Integer. + # With no block given, each element in `self` must respond to method `#<=>` with + # a numeric. # # With no argument and no block, returns the element in `self` having the - # minimum value per method `<=>`: + # minimum value per method `#<=>`: # - # [0, 1, 2].min # => 0 + # [1, 0, 3, 2].min # => 0 # - # With Integer argument `n` and no block, returns a new Array with at most `n` - # elements, in ascending order per method `<=>`: + # With non-negative numeric argument `n` and no block, returns a new array with + # at most `n` elements, in ascending order, per method `#<=>`: # - # [0, 1, 2, 3].min(3) # => [0, 1, 2] - # [0, 1, 2, 3].min(6) # => [0, 1, 2, 3] + # [1, 0, 3, 2].min(3) # => [0, 1, 2] + # [1, 0, 3, 2].min(3.0) # => [0, 1, 2] + # [1, 0, 3, 2].min(9) # => [0, 1, 2, 3] + # [1, 0, 3, 2].min(0) # => [] # - # When a block is given, the block must return an Integer. + # With a block given, the block must return a numeric. # - # With a block and no argument, calls the block `self.size-1` times to compare + # With a block and no argument, calls the block `self.size - 1` times to compare # elements; returns the element having the minimum value per the block: # - # ['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0" + # ['0', '', '000', '00'].min {|a, b| a.size <=> b.size } + # # => "" + # + # With non-negative numeric argument `n` and a block, returns a new array with + # at most `n` elements, in ascending order, per the block: # - # With an argument `n` and a block, returns a new Array with at most `n` - # elements, in ascending order per the block: + # ['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size } + # # => ["", "0"] # - # ['0', '00', '000'].min(2) {|a, b| a.size <=> b.size } # => ["0", "00"] + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # alias min max # - # Returns a new 2-element Array containing the minimum and maximum values from - # `self`, either per method `<=>` or per a given block:. + # Returns a 2-element array containing the minimum-valued and maximum-valued + # elements from `self`; does not modify `self`. # - # When no block is given, each element in `self` must respond to method `<=>` - # with an Integer; returns a new 2-element Array containing the minimum and - # maximum values from `self`, per method `<=>`: + # With no block given, the minimum and maximum values are determined using + # method `#<=>`: # - # [0, 1, 2].minmax # => [0, 2] + # [1, 0, 3, 2].minmax # => [0, 3] # - # When a block is given, the block must return an Integer; the block is called - # `self.size-1` times to compare elements; returns a new 2-element Array - # containing the minimum and maximum values from `self`, per the block: + # With a block given, the block must return a numeric; the block is called + # `self.size - 1` times to compare elements; returns the elements having the + # minimum and maximum values per the block: # - # ['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"] + # ['0', '', '000', '00'].minmax {|a, b| a.size <=> b.size } + # # => ["", "000"] + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def minmax: () -> [ Elem?, Elem? ] | () { (Elem a, Elem b) -> ::Integer? } -> [ Elem?, Elem? ] # - # Returns `true` if no element of `self` meet a given criterion. + # Returns `true` if no element of `self` meets a given criterion, `false` + # otherwise. # # With no block given and no argument, returns `true` if `self` has no truthy # elements, `false` otherwise: # - # [nil, false].none? # => true + # [nil, false].none? # => true # [nil, 0, false].none? # => false - # [].none? # => true - # - # With a block given and no argument, calls the block with each element in - # `self`; returns `true` if the block returns no truthy value, `false` - # otherwise: + # [].none? # => true # - # [0, 1, 2].none? {|element| element > 3 } # => true - # [0, 1, 2].none? {|element| element > 1 } # => false - # - # If argument `obj` is given, returns `true` if `obj.===` no element, `false` - # otherwise: + # With argument `object` given, returns `false` if for any element `element`, + # `object === element`; `true` otherwise: # # ['food', 'drink'].none?(/bar/) # => true # ['food', 'drink'].none?(/foo/) # => false - # [].none?(/foo/) # => true - # [0, 1, 2].none?(3) # => true - # [0, 1, 2].none?(1) # => false + # [].none?(/foo/) # => true + # [0, 1, 2].none?(3) # => true + # [0, 1, 2].none?(1) # => false + # + # With a block given, calls the block with each element in `self`; returns + # `true` if the block returns no truthy value, `false` otherwise: + # + # [0, 1, 2].none? {|element| element > 3 } # => true + # [0, 1, 2].none? {|element| element > 1 } # => false # - # Related: Enumerable#none? + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # alias none? all? # # Returns `true` if exactly one element of `self` meets a given criterion. # @@ -2417,16 +2554,15 @@ class Array[unchecked out Elem] < Object # [nil, nil].one? # => false # [].one? # => false # - # With a block given and no argument, calls the block with each element in - # `self`; returns `true` if the block a truthy value for exactly one element, - # `false` otherwise: + # With a block given, calls the block with each element in `self`; returns + # `true` if the block a truthy value for exactly one element, `false` otherwise: # # [0, 1, 2].one? {|element| element > 0 } # => false # [0, 1, 2].one? {|element| element > 1 } # => true # [0, 1, 2].one? {|element| element > 2 } # => false # - # If argument `obj` is given, returns `true` if `obj.===` exactly one element, - # `false` otherwise: + # With argument `object` given, returns `true` if for exactly one element + # `element`, `object === element`; `false` otherwise: # # [0, 1, 2].one?(0) # => true # [0, 0, 1].one?(0) # => false @@ -2435,7 +2571,7 @@ class Array[unchecked out Elem] < Object # ['food', 'drink'].one?(/foo/) # => true # [].one?(/foo/) # => false # - # Related: Enumerable#one? + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # alias one? none? @@ -2450,114 +2586,76 @@ class Array[unchecked out Elem] < Object # - # When invoked with a block, yield all permutations of elements of `self`; - # returns `self`. The order of permutations is indeterminate. - # - # When a block and an in-range positive Integer argument `n` (`0 < n <= - # self.size`) are given, calls the block with all `n`-tuple permutations of - # `self`. - # - # Example: - # - # a = [0, 1, 2] - # a.permutation(2) {|permutation| p permutation } - # - # Output: - # - # [0, 1] - # [0, 2] - # [1, 0] - # [1, 2] - # [2, 0] - # [2, 1] + # Iterates over permutations of the elements of `self`; the order of + # permutations is indeterminate. # - # Another example: + # With a block and an in-range positive integer argument `n` (`0 < n <= + # self.size`) given, calls the block with each `n`-tuple permutations of `self`; + # returns `self`: # # a = [0, 1, 2] - # a.permutation(3) {|permutation| p permutation } - # - # Output: - # - # [0, 1, 2] - # [0, 2, 1] - # [1, 0, 2] - # [1, 2, 0] - # [2, 0, 1] - # [2, 1, 0] + # perms = [] + # a.permutation(1) {|perm| perms.push(perm) } + # perms # => [[0], [1], [2]] # - # When `n` is zero, calls the block once with a new empty Array: + # perms = [] + # a.permutation(2) {|perm| perms.push(perm) } + # perms # => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]] # - # a = [0, 1, 2] - # a.permutation(0) {|permutation| p permutation } + # perms = [] + # a.permutation(3) {|perm| perms.push(perm) } + # perms # => [[0, 1, 2], [0, 2, 1], [1, 0, 2], [1, 2, 0], [2, 0, 1], [2, 1, 0]] # - # Output: + # When `n` is zero, calls the block once with a new empty array: # - # [] + # perms = [] + # a.permutation(0) {|perm| perms.push(perm) } + # perms # => [[]] # # When `n` is out of range (negative or larger than `self.size`), does not call # the block: # - # a = [0, 1, 2] # a.permutation(-1) {|permutation| fail 'Cannot happen' } # a.permutation(4) {|permutation| fail 'Cannot happen' } # - # When a block given but no argument, behaves the same as - # `a.permutation(a.size)`: - # - # a = [0, 1, 2] - # a.permutation {|permutation| p permutation } - # - # Output: + # With no block given, returns a new Enumerator. # - # [0, 1, 2] - # [0, 2, 1] - # [1, 0, 2] - # [1, 2, 0] - # [2, 0, 1] - # [2, 1, 0] - # - # Returns a new Enumerator if no block given: - # - # a = [0, 1, 2] - # a.permutation # => # - # a.permutation(2) # => # + # Related: [Methods for Iterating](rdoc-ref:Array@Methods+for+Iterating). # def permutation: (?int n) -> ::Enumerator[::Array[Elem], ::Array[Elem]] | (?int n) { (::Array[Elem] p) -> void } -> ::Array[Elem] # - # Removes and returns trailing elements. + # Removes and returns trailing elements of `self`. # - # When no argument is given and `self` is not empty, removes and returns the - # last element: + # With no argument given, removes and returns the last element, if available; + # otherwise returns `nil`: # # a = [:foo, 'bar', 2] - # a.pop # => 2 - # a # => [:foo, "bar"] - # - # Returns `nil` if the array is empty. + # a.pop # => 2 + # a # => [:foo, "bar"] + # [].pop # => nil # - # When a non-negative Integer argument `n` is given and is in range, + # With non-negative integer argument `count` given, returns a new array + # containing the trailing `count` elements of `self`, as available: # - # removes and returns the last `n` elements in a new Array: # a = [:foo, 'bar', 2] # a.pop(2) # => ["bar", 2] - # - # If `n` is positive and out of range, removes and returns all elements: + # a # => [:foo] # # a = [:foo, 'bar', 2] # a.pop(50) # => [:foo, "bar", 2] + # a # => [] # - # Related: #push, #shift, #unshift. + # Related: Array#push; see also [Methods for + # Deleting](rdoc-ref:Array@Methods+for+Deleting). # def pop: () -> Elem? | (int n) -> ::Array[Elem] @@ -2568,67 +2666,63 @@ class Array[unchecked out Elem] < Object # a = [:foo, 'bar', 2] # a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] # - # Related: #push, #pop, #shift. + # Related: Array#shift; see also [Methods for + # Assigning](rdoc-ref:Array@Methods+for+Assigning). # alias prepend unshift # - # Computes and returns or yields all combinations of elements from all the - # Arrays, including both `self` and `other_arrays`: + # Computes all combinations of elements from all the arrays, including both + # `self` and `other_arrays`: # # * The number of combinations is the product of the sizes of all the arrays, # including both `self` and `other_arrays`. # * The order of the returned combinations is indeterminate. # - # When no block is given, returns the combinations as an Array of Arrays: + # With no block given, returns the combinations as an array of arrays: # - # a = [0, 1, 2] - # a1 = [3, 4] - # a2 = [5, 6] - # p = a.product(a1) - # p.size # => 6 # a.size * a1.size - # p # => [[0, 3], [0, 4], [1, 3], [1, 4], [2, 3], [2, 4]] - # p = a.product(a1, a2) - # p.size # => 12 # a.size * a1.size * a2.size - # p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]] - # - # If any argument is an empty Array, returns an empty Array. - # - # If no argument is given, returns an Array of 1-element Arrays, each containing - # an element of `self`: + # p = [0, 1].product([2, 3]) + # # => [[0, 2], [0, 3], [1, 2], [1, 3]] + # p.size # => 4 + # p = [0, 1].product([2, 3], [4, 5]) + # # => [[0, 2, 4], [0, 2, 5], [0, 3, 4], [0, 3, 5], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3,... + # p.size # => 8 # - # a.product # => [[0], [1], [2]] + # If `self` or any argument is empty, returns an empty array: # - # When a block is given, yields each combination as an Array; returns `self`: + # [].product([2, 3], [4, 5]) # => [] + # [0, 1].product([2, 3], []) # => [] # - # a.product(a1) {|combination| p combination } + # If no argument is given, returns an array of 1-element arrays, each containing + # an element of `self`: # - # Output: + # a.product # => [[0], [1], [2]] # - # [0, 3] - # [0, 4] - # [1, 3] - # [1, 4] - # [2, 3] - # [2, 4] + # With a block given, calls the block with each combination; returns `self`: # - # If any argument is an empty Array, does not call the block: + # p = [] + # [0, 1].product([2, 3]) {|combination| p.push(combination) } + # p # => [[0, 2], [0, 3], [1, 2], [1, 3]] # - # a.product(a1, a2, []) {|combination| fail 'Cannot happen' } + # If `self` or any argument is empty, does not call the block: # - # If no argument is given, yields each element of `self` as a 1-element Array: + # [].product([2, 3], [4, 5]) {|combination| fail 'Cannot happen' } + # # => [] + # [0, 1].product([2, 3], []) {|combination| fail 'Cannot happen' } + # # => [0, 1] # - # a.product {|combination| p combination } + # If no argument is given, calls the block with each element of `self` as a + # 1-element array: # - # Output: + # p = [] + # [0, 1].product {|combination| p.push(combination) } + # p # => [[0], [1]] # - # [0] - # [1] - # [2] + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def product: () -> ::Array[[ Elem ]] | [X] (::Array[X] other_ary) -> ::Array[[ Elem, X ]] @@ -2637,66 +2731,66 @@ class Array[unchecked out Elem] < Object # - # Appends trailing elements. + # Appends each argument in `objects` to `self`; returns `self`: # - # Appends each argument in `objects` to `self`; returns `self`: + # a = [:foo, 'bar', 2] # => [:foo, "bar", 2] + # a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] # - # a = [:foo, 'bar', 2] - # a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] + # Appends each argument as a single element, even if it is another array: # - # Appends each argument as one element, even if it is another Array: + # a = [:foo, 'bar', 2] # => [:foo, "bar", 2] + # a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] # - # a = [:foo, 'bar', 2] - # a1 = a.push([:baz, :bat], [:bam, :bad]) - # a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] - # - # Related: #pop, #shift, #unshift. + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def push: (*Elem obj) -> self # - # Returns the first element in `self` that is an Array whose second element `==` - # `obj`: + # Returns the first element `ele` in `self` such that `ele` is an array and + # `ele[1] == object`: # # a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] # a.rassoc(4) # => [2, 4] + # a.rassoc(5) # => [4, 5, 6] # # Returns `nil` if no such element is found. # - # Related: #assoc. + # Related: Array#assoc; see also [Methods for + # Fetching](rdoc-ref:Array@Methods+for+Fetching). # alias rassoc assoc # - # Returns a new Array whose elements are all those from `self` for which the - # block returns `false` or `nil`: + # With a block given, returns a new array whose elements are all those from + # `self` for which the block returns `false` or `nil`: # # a = [:foo, 'bar', 2, 'bat'] # a1 = a.reject {|element| element.to_s.start_with?('b') } # a1 # => [:foo, 2] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # a.reject # => # + # Related: [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # alias reject delete_if # - # Removes each element for which the block returns a truthy value. + # With a block given, calls the block with each element of `self`; removes each + # element for which the block returns a truthy value. # # Returns `self` if any elements removed: # @@ -2705,257 +2799,184 @@ class Array[unchecked out Elem] < Object # # Returns `nil` if no elements removed. # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2] - # a.reject! # => # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def reject!: () { (Elem item) -> boolish } -> self? | () -> ::Enumerator[Elem, self?] # - # Calls the block with each repeated combination of length `n` of the elements - # of `self`; each combination is an Array; returns `self`. The order of the - # combinations is indeterminate. - # - # When a block and a positive Integer argument `n` are given, calls the block - # with each `n`-tuple repeated combination of the elements of `self`. The number - # of combinations is `(n+1)(n+2)/2`. - # - # `n` = 1: - # - # a = [0, 1, 2] - # a.repeated_combination(1) {|combination| p combination } - # - # Output: + # With a block given, calls the block with each repeated combination of length + # `size` of the elements of `self`; each combination is an array; returns + # `self`. The order of the combinations is indeterminate. # - # [0] - # [1] - # [2] + # If a positive integer argument `size` is given, calls the block with each + # `size`-tuple repeated combination of the elements of `self`. The number of + # combinations is `(size+1)(size+2)/2`. # - # `n` = 2: + # Examples: # - # a.repeated_combination(2) {|combination| p combination } + # * `size` is 1: # - # Output: + # c = [] + # [0, 1, 2].repeated_combination(1) {|combination| c.push(combination) } + # c # => [[0], [1], [2]] # - # [0, 0] - # [0, 1] - # [0, 2] - # [1, 1] - # [1, 2] - # [2, 2] + # * `size` is 2: # - # If `n` is zero, calls the block once with an empty Array. + # c = [] + # [0, 1, 2].repeated_combination(2) {|combination| c.push(combination) } + # c # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]] # - # If `n` is negative, does not call the block: + # If `size` is zero, calls the block once with an empty array. # - # a.repeated_combination(-1) {|combination| fail 'Cannot happen' } + # If `size` is negative, does not call the block: # - # Returns a new Enumerator if no block given: + # [0, 1, 2].repeated_combination(-1) {|combination| fail 'Cannot happen' } # - # a = [0, 1, 2] - # a.repeated_combination(2) # => # + # With no block given, returns a new Enumerator. # - # Using Enumerators, it's convenient to show the combinations and counts for - # some values of `n`: - # - # e = a.repeated_combination(0) - # e.size # => 1 - # e.to_a # => [[]] - # e = a.repeated_combination(1) - # e.size # => 3 - # e.to_a # => [[0], [1], [2]] - # e = a.repeated_combination(2) - # e.size # => 6 - # e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 1], [1, 2], [2, 2]] + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def repeated_combination: (int n) { (::Array[Elem] c) -> void } -> self | (int n) -> ::Enumerator[::Array[Elem], self] # - # Calls the block with each repeated permutation of length `n` of the elements - # of `self`; each permutation is an Array; returns `self`. The order of the - # permutations is indeterminate. - # - # When a block and a positive Integer argument `n` are given, calls the block - # with each `n`-tuple repeated permutation of the elements of `self`. The number - # of permutations is `self.size**n`. - # - # `n` = 1: - # - # a = [0, 1, 2] - # a.repeated_permutation(1) {|permutation| p permutation } - # - # Output: + # With a block given, calls the block with each repeated permutation of length + # `size` of the elements of `self`; each permutation is an array; returns + # `self`. The order of the permutations is indeterminate. # - # [0] - # [1] - # [2] + # If a positive integer argument `size` is given, calls the block with each + # `size`-tuple repeated permutation of the elements of `self`. The number of + # permutations is `self.size**size`. # - # `n` = 2: + # Examples: # - # a.repeated_permutation(2) {|permutation| p permutation } + # * `size` is 1: # - # Output: + # p = [] + # [0, 1, 2].repeated_permutation(1) {|permutation| p.push(permutation) } + # p # => [[0], [1], [2]] # - # [0, 0] - # [0, 1] - # [0, 2] - # [1, 0] - # [1, 1] - # [1, 2] - # [2, 0] - # [2, 1] - # [2, 2] + # * `size` is 2: # - # If `n` is zero, calls the block once with an empty Array. + # p = [] + # [0, 1, 2].repeated_permutation(2) {|permutation| p.push(permutation) } + # p # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] # - # If `n` is negative, does not call the block: + # If `size` is zero, calls the block once with an empty array. # - # a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' } + # If `size` is negative, does not call the block: # - # Returns a new Enumerator if no block given: - # - # a = [0, 1, 2] - # a.repeated_permutation(2) # => # + # [0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' } # - # Using Enumerators, it's convenient to show the permutations and counts for - # some values of `n`: + # With no block given, returns a new Enumerator. # - # e = a.repeated_permutation(0) - # e.size # => 1 - # e.to_a # => [[]] - # e = a.repeated_permutation(1) - # e.size # => 3 - # e.to_a # => [[0], [1], [2]] - # e = a.repeated_permutation(2) - # e.size # => 9 - # e.to_a # => [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def repeated_permutation: (int n) { (::Array[Elem] p) -> void } -> self | (int n) -> ::Enumerator[::Array[Elem], self] # - # Replaces the content of `self` with the content of `other_array`; returns + # Replaces the elements of `self` with the elements of `other_array`, which must + # be an [array-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects); returns # `self`: # - # a = [:foo, 'bar', 2] - # a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.replace(['d', 'e']) # => ["d", "e"] + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def replace: (::Array[Elem]) -> self # - # Returns a new Array with the elements of `self` in reverse order: + # Returns a new array containing the elements of `self` in reverse order: + # + # [0, 1, 2].reverse # => [2, 1, 0] # - # a = ['foo', 'bar', 'two'] - # a1 = a.reverse - # a1 # => ["two", "bar", "foo"] + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def reverse: () -> ::Array[Elem] # - # Reverses `self` in place: + # Reverses the order of the elements of `self`; returns `self`: + # + # a = [0, 1, 2] + # a.reverse! # => [2, 1, 0] + # a # => [2, 1, 0] # - # a = ['foo', 'bar', 'two'] - # a.reverse! # => ["two", "bar", "foo"] + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def reverse!: () -> ::Array[Elem] # - # Iterates backwards over array elements. + # When a block given, iterates backwards over the elements of `self`, passing, + # in reverse order, each element to the block; returns `self`: # - # When a block given, passes, in reverse order, each element to the block; - # returns `self`: - # - # a = [:foo, 'bar', 2] - # a.reverse_each {|element| puts "#{element.class} #{element}" } - # - # Output: - # - # Integer 2 - # String bar - # Symbol foo + # a = [] + # [0, 1, 2].reverse_each {|element| a.push(element) } + # a # => [2, 1, 0] # # Allows the array to be modified during iteration: # - # a = [:foo, 'bar', 2] - # a.reverse_each {|element| puts element; a.clear if element.to_s.start_with?('b') } - # - # Output: - # - # 2 - # bar - # - # When no block given, returns a new Enumerator: + # a = ['a', 'b', 'c'] + # a.reverse_each {|element| a.clear if element.start_with?('b') } + # a # => [] # - # a = [:foo, 'bar', 2] - # e = a.reverse_each - # e # => # - # a1 = e.each {|element| puts "#{element.class} #{element}" } - # - # Output: - # - # Integer 2 - # String bar - # Symbol foo + # When no block given, returns a new Enumerator. # - # Related: #each, #each_index. + # Related: see [Methods for Iterating](rdoc-ref:Array@Methods+for+Iterating). # def reverse_each: () { (Elem item) -> void } -> self | () -> ::Enumerator[Elem, self] # # Returns the index of the last element for which `object == element`. # - # When argument `object` is given but no block, returns the index of the last - # such element found: + # With argument `object` given, returns the index of the last such element + # found: # # a = [:foo, 'bar', 2, 'bar'] # a.rindex('bar') # => 3 # # Returns `nil` if no such object found. # - # When a block is given but no argument, calls the block with each successive - # element; returns the index of the last element for which the block returns a - # truthy value: + # With a block given, calls the block with each successive element; returns the + # index of the last element for which the block returns a truthy value: # # a = [:foo, 'bar', 2, 'bar'] # a.rindex {|element| element == 'bar' } # => 3 # # Returns `nil` if the block never returns a truthy value. # - # When neither an argument nor a block is given, returns a new Enumerator: + # When neither an argument nor a block is given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, 'bar'] - # e = a.rindex - # e # => # - # e.each {|element| element == 'bar' } # => 3 - # - # Related: #index. + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # def rindex: (untyped obj) -> ::Integer? | () { (Elem item) -> boolish } -> ::Integer? @@ -2963,167 +2984,155 @@ class Array[unchecked out Elem] < Object # - # Returns a new Array formed from `self` with elements rotated from one end to + # Returns a new array formed from `self` with elements rotated from one end to # the other. # - # When no argument given, returns a new Array that is like `self`, except that - # the first element has been rotated to the last position: - # - # a = [:foo, 'bar', 2, 'bar'] - # a1 = a.rotate - # a1 # => ["bar", 2, "bar", :foo] - # - # When given a non-negative Integer `count`, returns a new Array with `count` - # elements rotated from the beginning to the end: + # With non-negative numeric `count`, rotates elements from the beginning to the + # end: # - # a = [:foo, 'bar', 2] - # a1 = a.rotate(2) - # a1 # => [2, :foo, "bar"] + # [0, 1, 2, 3].rotate(2) # => [2, 3, 0, 1] + # [0, 1, 2, 3].rotate(2.1) # => [2, 3, 0, 1] # # If `count` is large, uses `count % array.size` as the count: # - # a = [:foo, 'bar', 2] - # a1 = a.rotate(20) - # a1 # => [2, :foo, "bar"] + # [0, 1, 2, 3].rotate(22) # => [2, 3, 0, 1] # - # If `count` is zero, returns a copy of `self`, unmodified: + # With a `count` of zero, rotates no elements: # - # a = [:foo, 'bar', 2] - # a1 = a.rotate(0) - # a1 # => [:foo, "bar", 2] + # [0, 1, 2, 3].rotate(0) # => [0, 1, 2, 3] # - # When given a negative Integer `count`, rotates in the opposite direction, from - # end to beginning: + # With negative numeric `count`, rotates in the opposite direction, from the end + # to the beginning: # - # a = [:foo, 'bar', 2] - # a1 = a.rotate(-2) - # a1 # => ["bar", 2, :foo] + # [0, 1, 2, 3].rotate(-1) # => [3, 0, 1, 2] # # If `count` is small (far from zero), uses `count % array.size` as the count: # - # a = [:foo, 'bar', 2] - # a1 = a.rotate(-5) - # a1 # => ["bar", 2, :foo] + # [0, 1, 2, 3].rotate(-21) # => [3, 0, 1, 2] + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def rotate: (?int count) -> ::Array[Elem] # # Rotates `self` in place by moving elements from one end to the other; returns # `self`. # - # When no argument given, rotates the first element to the last position: - # - # a = [:foo, 'bar', 2, 'bar'] - # a.rotate! # => ["bar", 2, "bar", :foo] - # - # When given a non-negative Integer `count`, rotates `count` elements from the - # beginning to the end: + # With non-negative numeric `count`, rotates `count` elements from the beginning + # to the end: # - # a = [:foo, 'bar', 2] - # a.rotate!(2) - # a # => [2, :foo, "bar"] + # [0, 1, 2, 3].rotate!(2) # => [2, 3, 0, 1] + # [0, 1, 2, 3].rotate!(2.1) # => [2, 3, 0, 1] # # If `count` is large, uses `count % array.size` as the count: # - # a = [:foo, 'bar', 2] - # a.rotate!(20) - # a # => [2, :foo, "bar"] + # [0, 1, 2, 3].rotate!(21) # => [1, 2, 3, 0] # - # If `count` is zero, returns `self` unmodified: + # If `count` is zero, rotates no elements: # - # a = [:foo, 'bar', 2] - # a.rotate!(0) - # a # => [:foo, "bar", 2] + # [0, 1, 2, 3].rotate!(0) # => [0, 1, 2, 3] # - # When given a negative Integer `count`, rotates in the opposite direction, from - # end to beginning: + # With a negative numeric `count`, rotates in the opposite direction, from end + # to beginning: # - # a = [:foo, 'bar', 2] - # a.rotate!(-2) - # a # => ["bar", 2, :foo] + # [0, 1, 2, 3].rotate!(-1) # => [3, 0, 1, 2] # # If `count` is small (far from zero), uses `count % array.size` as the count: # - # a = [:foo, 'bar', 2] - # a.rotate!(-5) - # a # => ["bar", 2, :foo] + # [0, 1, 2, 3].rotate!(-21) # => [3, 0, 1, 2] + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def rotate!: (?int count) -> self # - # Returns random elements from `self`. + # Returns random elements from `self`, as selected by the object given by + # keyword argument `random`. # - # When no arguments are given, returns a random element from `self`: - # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] + # With no argument `count` given, returns one random element from `self`: + # + # a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # a.sample # => 3 # a.sample # => 8 # - # If `self` is empty, returns `nil`. + # Returns `nil` if `self` is empty: + # + # [].sample # => nil + # + # With non-negative numeric argument `count` given, returns a new array + # containing `count` random elements from `self`: # - # When argument `n` is given, returns a new Array containing `n` random elements - # from `self`: # a.sample(3) # => [8, 9, 2] - # a.sample(6) # => [9, 6, 10, 3, 1, 4] + # a.sample(6) # => [9, 6, 0, 3, 1, 4] + # + # The order of the result array is unrelated to the order of `self`. + # + # Returns a new empty `Array` if `self` is empty: + # + # [].sample(4) # => [] + # + # May return duplicates in `self`: + # + # a = [1, 1, 1, 2, 2, 3] + # a.sample(a.size) # => [1, 1, 3, 2, 1, 2] # # Returns no more than `a.size` elements (because no new duplicates are # introduced): - # a.sample(a.size * 2) # => [6, 4, 1, 8, 5, 9, 10, 2, 3, 7] # - # But `self` may contain duplicates: - # a = [1, 1, 1, 2, 2, 3] - # a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2] + # a.sample(50) # => [6, 4, 1, 8, 5, 9, 0, 2, 3, 7] # - # The argument `n` must be a non-negative numeric value. The order of the result - # array is unrelated to the order of `self`. Returns a new empty Array if `self` - # is empty. + # The object given with keyword argument `random` is used as the random number + # generator: # - # The optional `random` argument will be used as the random number generator: # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] # a.sample(random: Random.new(1)) #=> 6 # a.sample(4, random: Random.new(1)) #=> [6, 10, 9, 2] # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def sample: %a{implicitly-returns-nil} (?random: _Rand rng) -> Elem | (int n, ?random: _Rand rng) -> ::Array[Elem] # - # Calls the block, if given, with each element of `self`; returns a new Array - # containing those elements of `self` for which the block returns a truthy + # With a block given, calls the block with each element of `self`; returns a new + # array containing those elements of `self` for which the block returns a truthy # value: # # a = [:foo, 'bar', 2, :bam] - # a1 = a.select {|element| element.to_s.start_with?('b') } - # a1 # => ["bar", :bam] + # a.select {|element| element.to_s.start_with?('b') } + # # => ["bar", :bam] # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, :bam] - # a.select # => # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def select: () { (Elem item) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] # - # Calls the block, if given with each element of `self`; removes from `self` - # those elements for which the block returns `false` or `nil`. + # With a block given, calls the block with each element of `self`; removes from + # `self` those elements for which the block returns `false` or `nil`. # # Returns `self` if any elements were removed: # @@ -3132,86 +3141,131 @@ class Array[unchecked out Elem] < Object # # Returns `nil` if no elements were removed. # - # Returns a new Enumerator if no block given: + # With no block given, returns a new Enumerator. # - # a = [:foo, 'bar', 2, :bam] - # a.select! # => # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def select!: () { (Elem item) -> boolish } -> self? | () -> ::Enumerator[Elem, self?] # - # Removes and returns leading elements. + # Removes and returns leading elements from `self`. # - # When no argument is given, removes and returns the first element: - # - # a = [:foo, 'bar', 2] - # a.shift # => :foo - # a # => ['bar', 2] + # With no argument, removes and returns one element, if available, or `nil` + # otherwise: # - # Returns `nil` if `self` is empty. + # a = [0, 1, 2, 3] + # a.shift # => 0 + # a # => [1, 2, 3] + # [].shift # => nil # - # When positive Integer argument `n` is given, removes the first `n` elements; - # returns those elements in a new Array: + # With non-negative numeric argument `count` given, removes and returns the + # first `count` elements: # - # a = [:foo, 'bar', 2] - # a.shift(2) # => [:foo, 'bar'] - # a # => [2] + # a = [0, 1, 2, 3] + # a.shift(2) # => [0, 1] + # a # => [2, 3] + # a.shift(1.1) # => [2] + # a # => [3] + # a.shift(0) # => [] + # a # => [3] # - # If `n` is as large as or larger than `self.length`, removes all elements; - # returns those elements in a new Array: + # If `count` is large, removes and returns all elements: # - # a = [:foo, 'bar', 2] - # a.shift(3) # => [:foo, 'bar', 2] + # a = [0, 1, 2, 3] + # a.shift(50) # => [0, 1, 2, 3] + # a # => [] # - # If `n` is zero, returns a new empty Array; `self` is unmodified. + # If `self` is empty, returns a new empty array. # - # Related: #push, #pop, #unshift. + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def shift: %a{implicitly-returns-nil} () -> Elem | (int n) -> ::Array[Elem] # - # Returns a new array with elements of `self` shuffled. - # a = [1, 2, 3] #=> [1, 2, 3] - # a.shuffle #=> [2, 3, 1] - # a #=> [1, 2, 3] + # Returns a new array containing all elements from `self` in a random order, as + # selected by the object given by keyword argument `random`: + # + # a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + # a.shuffle # => [0, 8, 1, 9, 6, 3, 4, 7, 2, 5] + # a.shuffle # => [8, 9, 0, 5, 1, 2, 6, 4, 7, 3] + # + # Duplicate elements are included: + # + # a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + # a.shuffle # => [1, 0, 1, 1, 0, 0, 1, 0, 0, 1] + # a.shuffle # => [1, 1, 0, 0, 0, 1, 1, 0, 0, 1] + # + # The object given with keyword argument `random` is used as the random number + # generator. # - # The optional `random` argument will be used as the random number generator: - # a.shuffle(random: Random.new(1)) #=> [1, 3, 2] + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def shuffle: (?random: _Rand rng) -> ::Array[Elem] # - # Shuffles the elements of `self` in place. - # a = [1, 2, 3] #=> [1, 2, 3] - # a.shuffle! #=> [2, 3, 1] - # a #=> [2, 3, 1] + # Shuffles all elements in `self` into a random order, as selected by the object + # given by keyword argument `random`; returns `self`: # - # The optional `random` argument will be used as the random number generator: - # a.shuffle!(random: Random.new(1)) #=> [1, 3, 2] + # a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + # a.shuffle! # => [5, 3, 8, 7, 6, 1, 9, 4, 2, 0] + # a.shuffle! # => [9, 4, 0, 6, 2, 8, 1, 5, 3, 7] + # + # Duplicate elements are included: + # + # a = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1] + # a.shuffle! # => [1, 0, 0, 1, 1, 0, 1, 0, 0, 1] + # a.shuffle! # => [0, 1, 0, 1, 1, 0, 1, 0, 1, 0] + # + # The object given with keyword argument `random` is used as the random number + # generator. + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def shuffle!: (?random: _Rand rng) -> self # - # Returns the count of elements in `self`. + # Returns the count of elements in `self`: + # + # [0, 1, 2].length # => 3 + # [].length # => 0 + # + # Related: see [Methods for Querying](rdoc-ref:Array@Methods+for+Querying). # alias size length # # Returns elements from `self`; does not modify `self`. # - # When a single Integer argument `index` is given, returns the element at offset + # In brief: + # + # a = [:foo, 'bar', 2] + # + # # Single argument index: returns one element. + # a[0] # => :foo # Zero-based index. + # a[-1] # => 2 # Negative index counts backwards from end. + # + # # Arguments start and length: returns an array. + # a[1, 2] # => ["bar", 2] + # a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end. + # + # # Single argument range: returns an array. + # a[0..1] # => [:foo, "bar"] + # a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end. + # a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end. + # + # When a single integer argument `index` is given, returns the element at offset # `index`: # # a = [:foo, 'bar', 2] @@ -3219,7 +3273,7 @@ class Array[unchecked out Elem] < Object # a[2] # => 2 # a # => [:foo, "bar", 2] # - # If `index` is negative, counts relative to the end of `self`: + # If `index` is negative, counts backwards from the end of `self`: # # a = [:foo, 'bar', 2] # a[-1] # => 2 @@ -3227,8 +3281,9 @@ class Array[unchecked out Elem] < Object # # If `index` is out of range, returns `nil`. # - # When two Integer arguments `start` and `length` are given, returns a new Array - # of size `length` containing successive elements beginning at offset `start`: + # When two Integer arguments `start` and `length` are given, returns a new + # `Array` of size `length` containing successive elements beginning at offset + # `start`: # # a = [:foo, 'bar', 2] # a[0, 2] # => [:foo, "bar"] @@ -3242,7 +3297,7 @@ class Array[unchecked out Elem] < Object # a[1, 3] # => ["bar", 2] # a[2, 2] # => [2] # - # If `start == self.size` and `length >= 0`, returns a new empty Array. + # If `start == self.size` and `length >= 0`, returns a new empty `Array`. # # If `length` is negative, returns `nil`. # @@ -3253,7 +3308,7 @@ class Array[unchecked out Elem] < Object # a[0..1] # => [:foo, "bar"] # a[1..2] # => ["bar", 2] # - # Special case: If `range.start == a.size`, returns a new empty Array. + # Special case: If `range.start == a.size`, returns a new empty `Array`. # # If `range.end` is negative, calculates the end index from the end: # @@ -3277,7 +3332,7 @@ class Array[unchecked out Elem] < Object # a[4..-1] # => nil # # When a single Enumerator::ArithmeticSequence argument `aseq` is given, returns - # an Array of elements corresponding to the indexes produced by the sequence. + # an `Array` of elements corresponding to the indexes produced by the sequence. # # a = ['--', 'data1', '--', 'data2', '--', 'data3'] # a[(1..).step(2)] # => ["data1", "data2", "data3"] @@ -3298,75 +3353,100 @@ class Array[unchecked out Elem] < Object # # Raises TypeError (no implicit conversion of Symbol into Integer): # a[:foo] # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def slice: %a{implicitly-returns-nil} (int index) -> Elem | (int start, int length) -> ::Array[Elem]? | (::Range[::Integer] range) -> ::Array[Elem]? # # Removes and returns elements from `self`. # - # When the only argument is an Integer `n`, removes and returns the *nth* - # element in `self`: + # With numeric argument `index` given, removes and returns the element at offset + # `index`: # - # a = [:foo, 'bar', 2] - # a.slice!(1) # => "bar" - # a # => [:foo, 2] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(2) # => "c" + # a # => ["a", "b", "d"] + # a.slice!(2.1) # => "d" + # a # => ["a", "b"] # - # If `n` is negative, counts backwards from the end of `self`: + # If `index` is negative, counts backwards from the end of `self`: # - # a = [:foo, 'bar', 2] - # a.slice!(-1) # => 2 - # a # => [:foo, "bar"] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(-2) # => "c" + # a # => ["a", "b", "d"] # - # If `n` is out of range, returns `nil`. + # If `index` is out of range, returns `nil`. # - # When the only arguments are Integers `start` and `length`, removes `length` - # elements from `self` beginning at offset `start`; returns the deleted objects - # in a new Array: + # With numeric arguments `start` and `length` given, removes `length` elements + # from `self` beginning at zero-based offset `start`; returns the removed + # objects in a new array: # - # a = [:foo, 'bar', 2] - # a.slice!(0, 2) # => [:foo, "bar"] - # a # => [2] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(1, 2) # => ["b", "c"] + # a # => ["a", "d"] + # a.slice!(0.1, 1.1) # => ["a"] + # a # => ["d"] + # + # If `start` is negative, counts backwards from the end of `self`: + # + # a = ['a', 'b', 'c', 'd'] + # a.slice!(-2, 1) # => ["c"] + # a # => ["a", "b", "d"] + # + # If `start` is out-of-range, returns `nil`: + # + # a = ['a', 'b', 'c', 'd'] + # a.slice!(5, 1) # => nil + # a.slice!(-5, 1) # => nil # # If `start + length` exceeds the array size, removes and returns all elements # from offset `start` to the end: # - # a = [:foo, 'bar', 2] - # a.slice!(1, 50) # => ["bar", 2] - # a # => [:foo] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(2, 50) # => ["c", "d"] + # a # => ["a", "b"] # - # If `start == a.size` and `length` is non-negative, returns a new empty Array. + # If `start == a.size` and `length` is non-negative, returns a new empty array. # # If `length` is negative, returns `nil`. # - # When the only argument is a Range object `range`, treats `range.min` as - # `start` above and `range.size` as `length` above: + # With Range argument `range` given, treats `range.min` as `start` (as above) + # and `range.size` as `length` (as above): # - # a = [:foo, 'bar', 2] - # a.slice!(1..2) # => ["bar", 2] - # a # => [:foo] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(1..2) # => ["b", "c"] + # a # => ["a", "d"] # - # If `range.start == a.size`, returns a new empty Array. + # If `range.start == a.size`, returns a new empty array: # - # If `range.start` is larger than the array size, returns `nil`. + # a = ['a', 'b', 'c', 'd'] + # a.slice!(4..5) # => [] # - # If `range.end` is negative, counts backwards from the end of the array: + # If `range.start` is larger than the array size, returns `nil`: # - # a = [:foo, 'bar', 2] - # a.slice!(0..-2) # => [:foo, "bar"] - # a # => [2] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(5..6) # => nil # - # If `range.start` is negative, calculates the start index backwards from the - # end of the array: + # If `range.start` is negative, calculates the start index by counting backwards + # from the end of `self`: # - # a = [:foo, 'bar', 2] - # a.slice!(-2..2) # => ["bar", 2] - # a # => [:foo] + # a = ['a', 'b', 'c', 'd'] + # a.slice!(-2..2) # => ["c"] + # + # If `range.end` is negative, calculates the end index by counting backwards + # from the end of `self`: + # + # a = ['a', 'b', 'c', 'd'] + # a.slice!(0..-2) # => ["a", "b", "c"] + # + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def slice!: %a{implicitly-returns-nil} (int index) -> Elem | (int start, int length) -> ::Array[Elem]? @@ -3374,20 +3454,17 @@ class Array[unchecked out Elem] < Object # - # Returns a new Array whose elements are those from `self`, sorted. + # Returns a new array containing the elements of `self`, sorted. # - # With no block, compares elements using operator `<=>` (see Comparable): + # With no block given, compares elements using operator `#<=>` (see Object#<=>): # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a1 = a.sort - # a1 # => ["a", "b", "c", "d", "e"] + # [0, 2, 3, 1].sort # => [0, 1, 2, 3] # - # With a block, calls the block with each element pair; for each element pair - # `a` and `b`, the block should return an integer: + # With a block given, calls the block with each combination of pairs of elements + # from `self`; for each pair `a` and `b`, the block should return a numeric: # # * Negative when `b` is to follow `a`. # * Zero when `a` and `b` are equivalent. @@ -3395,131 +3472,92 @@ class Array[unchecked out Elem] < Object # # Example: # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a1 = a.sort {|a, b| a <=> b } - # a1 # => ["a", "b", "c", "d", "e"] - # a2 = a.sort {|a, b| b <=> a } - # a2 # => ["e", "d", "c", "b", "a"] + # a = [3, 2, 0, 1] + # a.sort {|a, b| a <=> b } # => [0, 1, 2, 3] + # a.sort {|a, b| b <=> a } # => [3, 2, 1, 0] # # When the block returns zero, the order for `a` and `b` is indeterminate, and - # may be unstable: - # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a1 = a.sort {|a, b| 0 } - # a1 # => ["c", "e", "b", "d", "a"] + # may be unstable. # - # Related: Enumerable#sort_by. + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def sort: () -> ::Array[Elem] | () { (Elem a, Elem b) -> ::Integer } -> ::Array[Elem] # - # Returns `self` with its elements sorted in place. - # - # With no block, compares elements using operator `<=>` (see Comparable): - # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a.sort! - # a # => ["a", "b", "c", "d", "e"] + # Like Array#sort, but returns `self` with its elements sorted in place. # - # With a block, calls the block with each element pair; for each element pair - # `a` and `b`, the block should return an integer: - # - # * Negative when `b` is to follow `a`. - # * Zero when `a` and `b` are equivalent. - # * Positive when `a` is to follow `b`. - # - # Example: - # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a.sort! {|a, b| a <=> b } - # a # => ["a", "b", "c", "d", "e"] - # a.sort! {|a, b| b <=> a } - # a # => ["e", "d", "c", "b", "a"] - # - # When the block returns zero, the order for `a` and `b` is indeterminate, and - # may be unstable: - # - # a = 'abcde'.split('').shuffle - # a # => ["e", "b", "d", "a", "c"] - # a.sort! {|a, b| 0 } - # a # => ["d", "e", "c", "a", "b"] + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def sort!: () -> self | () { (Elem a, Elem b) -> ::Integer } -> self # - # Sorts the elements of `self` in place, using an ordering determined by the - # block; returns self. + # With a block given, sorts the elements of `self` in place; returns self. # # Calls the block with each successive element; sorts elements based on the - # values returned from the block. - # - # For duplicates returned by the block, the ordering is indeterminate, and may - # be unstable. - # - # This example sorts strings based on their sizes: + # values returned from the block: # # a = ['aaaa', 'bbb', 'cc', 'd'] # a.sort_by! {|element| element.size } # a # => ["d", "cc", "bbb", "aaaa"] # - # Returns a new Enumerator if no block given: + # For duplicate values returned by the block, the ordering is indeterminate, and + # may be unstable. # - # a = ['aaaa', 'bbb', 'cc', 'd'] - # a.sort_by! # => # + # With no block given, returns a new Enumerator. + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def sort_by!: [U] () { (Elem obj) -> U } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] # - # When no block is given, returns the object equivalent to: + # With no block given, returns the sum of `init` and all elements of `self`; for + # array `array` and value `init`, equivalent to: # # sum = init # array.each {|element| sum += element } # sum # - # For example, `[e1, e2, e3].sum` returns `init + e1 + e2 + e3`. + # For example, `[e0, e1, e2].sum` returns `init + e0 + e1 + e2`. # # Examples: # - # a = [0, 1, 2, 3] - # a.sum # => 6 - # a.sum(100) # => 106 + # [0, 1, 2, 3].sum # => 6 + # [0, 1, 2, 3].sum(100) # => 106 + # ['abc', 'def', 'ghi'].sum('jkl') # => "jklabcdefghi" + # [[:foo, :bar], ['foo', 'bar']].sum([2, 3]) + # # => [2, 3, :foo, :bar, "foo", "bar"] # - # The elements need not be numeric, but must be `+`-compatible with each other - # and with `init`: + # The `init` value and elements need not be numeric, but must all be + # `+`-compatible: # - # a = ['abc', 'def', 'ghi'] - # a.sum('jkl') # => "jklabcdefghi" + # # Raises TypeError: Array can't be coerced into Integer. + # [[:foo, :bar], ['foo', 'bar']].sum(2) # - # When a block is given, it is called with each element and the block's return - # value (instead of the element itself) is used as the addend: + # With a block given, calls the block with each element of `self`; the block's + # return value (instead of the element itself) is used as the addend: # - # a = ['zero', 1, :two] - # s = a.sum('Coerced and concatenated: ') {|element| element.to_s } - # s # => "Coerced and concatenated: zero1two" + # ['zero', 1, :two].sum('Coerced and concatenated: ') {|element| element.to_s } + # # => "Coerced and concatenated: zero1two" # # Notes: # - # * Array#join and Array#flatten may be faster than Array#sum for an Array of - # Strings or an Array of Arrays. + # * Array#join and Array#flatten may be faster than Array#sum for an array of + # strings or an array of arrays. # * Array#sum method may not respect method redefinition of "+" methods such # as Integer#+. # @@ -3528,41 +3566,40 @@ class Array[unchecked out Elem] < Object # - # Returns a new Array containing the first `n` element of `self`, where `n` is a - # non-negative Integer; does not modify `self`. + # Returns a new array containing the first `count` element of `self` (as + # available); `count` must be a non-negative numeric; does not modify `self`: # - # Examples: + # a = ['a', 'b', 'c', 'd'] + # a.take(2) # => ["a", "b"] + # a.take(2.1) # => ["a", "b"] + # a.take(50) # => ["a", "b", "c", "d"] + # a.take(0) # => [] # - # a = [0, 1, 2, 3, 4, 5] - # a.take(1) # => [0] - # a.take(2) # => [0, 1] - # a.take(50) # => [0, 1, 2, 3, 4, 5] - # a # => [0, 1, 2, 3, 4, 5] + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def take: (int n) -> ::Array[Elem] # - # Returns a new Array containing zero or more leading elements of `self`; does - # not modify `self`. - # # With a block given, calls the block with each successive element of `self`; - # stops if the block returns `false` or `nil`; returns a new Array containing - # those elements for which the block returned a truthy value: + # stops iterating if the block returns `false` or `nil`; returns a new array + # containing those elements for which the block returned a truthy value: # # a = [0, 1, 2, 3, 4, 5] # a.take_while {|element| element < 3 } # => [0, 1, 2] - # a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5] - # a # => [0, 1, 2, 3, 4, 5] + # a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5] + # a.take_while {|element| false } # => [] # - # With no block given, returns a new Enumerator: + # With no block given, returns a new Enumerator. # - # [0, 1].take_while # => # + # Does not modify `self`. + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def take_while: () { (Elem obj) -> boolish } -> ::Array[Elem] | () -> ::Enumerator[Elem, ::Array[Elem]] @@ -3571,20 +3608,17 @@ class Array[unchecked out Elem] < Object # rdoc-file=array.c # - to_a -> self or new_array # --> - # When `self` is an instance of Array, returns `self`: - # - # a = [:foo, 'bar', 2] - # a.to_a # => [:foo, "bar", 2] + # When `self` is an instance of `Array`, returns `self`. # - # Otherwise, returns a new Array containing the elements of `self`: + # Otherwise, returns a new array containing the elements of `self`: # # class MyArray < Array; end - # a = MyArray.new(['foo', 'bar', 'two']) - # a.instance_of?(Array) # => false - # a.kind_of?(Array) # => true - # a1 = a.to_a - # a1 # => ["foo", "bar", "two"] - # a1.class # => Array # Not MyArray + # my_a = MyArray.new(['foo', 'bar', 'two']) + # a = my_a.to_a + # a # => ["foo", "bar", "two"] + # a.class # => Array # Not MyArray. + # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). # def to_a: () -> ::Array[Elem] @@ -3598,234 +3632,347 @@ class Array[unchecked out Elem] < Object # - # Returns a new Hash formed from `self`. + # Returns a new hash formed from `self`. # - # When a block is given, calls the block with each array element; the block must - # return a 2-element Array whose two elements form a key-value pair in the - # returned Hash: + # With no block given, each element of `self` must be a 2-element sub-array; + # forms each sub-array into a key-value pair in the new hash: # - # a = ['foo', :bar, 1, [2, 3], {baz: 4}] - # h = a.to_h {|item| [item, item] } - # h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}} + # a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']] + # a.to_h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"} + # [].to_h # => {} # - # When no block is given, `self` must be an Array of 2-element sub-arrays, each - # sub-array is formed into a key-value pair in the new Hash: + # With a block given, the block must return a 2-element array; calls the block + # with each element of `self`; forms each returned array into a key-value pair + # in the returned hash: # - # [].to_h # => {} - # a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']] - # h = a.to_h - # h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"} + # a = ['foo', :bar, 1, [2, 3], {baz: 4}] + # a.to_h {|element| [element, element.class] } + # # => {"foo"=>String, :bar=>Symbol, 1=>Integer, [2, 3]=>Array, {:baz=>4}=>Hash} + # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). # def to_h: () -> Hash[untyped, untyped] | [T, S] () { (Elem) -> [ T, S ] } -> Hash[T, S] # - # Returns the new String formed by calling method `#inspect` on each array + # Returns the new string formed by calling method `#inspect` on each array # element: # # a = [:foo, 'bar', 2] # a.inspect # => "[:foo, \"bar\", 2]" # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). + # alias to_s inspect # - # Transposes the rows and columns in an Array of Arrays; the nested Arrays must - # all be the same size: + # Returns a new array that is `self` as a [transposed + # matrix](https://en.wikipedia.org/wiki/Transpose): # # a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]] # a.transpose # => [[:a0, :b0, :c0], [:a1, :b1, :c1]] # + # The elements of `self` must all be the same size. + # + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). + # def transpose: () -> ::Array[::Array[untyped]] # - # Returns a new Array that is the union of `self` and all given Arrays - # `other_arrays`; duplicates are removed; order is preserved; items are - # compared using `eql?`: + # Returns a new array that is the union of the elements of `self` and all given + # arrays `other_arrays`; items are compared using `eql?`: # # [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7] + # + # Removes duplicates (preserving the first found): + # # [0, 1, 1].union([2, 1], [3, 1]) # => [0, 1, 2, 3] - # [0, 1, 2, 3].union([3, 2], [1, 0]) # => [0, 1, 2, 3] # - # Returns a copy of `self` if no arguments given. + # Preserves order (preserving the position of the first found): + # + # [3, 2, 1, 0].union([5, 3], [4, 2]) # => [3, 2, 1, 0, 5, 4] # - # Related: Array#|. + # With no arguments given, returns a copy of `self`. + # + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def union: [T] (*::Array[T] other_arys) -> ::Array[T | Elem] # - # Returns a new Array containing those elements from `self` that are not + # Returns a new array containing those elements from `self` that are not # duplicates, the first occurrence always being retained. # - # With no block given, identifies and omits duplicates using method `eql?` to - # compare: + # With no block given, identifies and omits duplicate elements using method + # `eql?` to compare elements: # # a = [0, 0, 1, 1, 2, 2] # a.uniq # => [0, 1, 2] # - # With a block given, calls the block for each element; identifies (using method - # `eql?`) and omits duplicate values, that is, those elements for which the - # block returns the same value: + # With a block given, calls the block for each element; identifies and omits + # "duplicate" elements using method `eql?` to compare *block return values*; + # that is, an element is a duplicate if its block return value is the same as + # that of a previous element: # # a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb'] # a.uniq {|element| element.size } # => ["a", "aa", "aaa"] # + # Related: [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). + # def uniq: () -> ::Array[Elem] | () { (Elem item) -> untyped } -> ::Array[Elem] # # Removes duplicate elements from `self`, the first occurrence always being # retained; returns `self` if any elements removed, `nil` otherwise. # # With no block given, identifies and removes elements using method `eql?` to - # compare. - # - # Returns `self` if any elements removed: + # compare elements: # # a = [0, 0, 1, 1, 2, 2] # a.uniq! # => [0, 1, 2] + # a.uniq! # => nil # - # Returns `nil` if no elements removed. - # - # With a block given, calls the block for each element; identifies (using method - # `eql?`) and removes elements for which the block returns duplicate values. - # - # Returns `self` if any elements removed: + # With a block given, calls the block for each element; identifies and omits + # "duplicate" elements using method `eql?` to compare *block return values*; + # that is, an element is a duplicate if its block return value is the same as + # that of a previous element: # # a = ['a', 'aa', 'aaa', 'b', 'bb', 'bbb'] - # a.uniq! {|element| element.size } # => ['a', 'aa', 'aaa'] + # a.uniq! {|element| element.size } # => ["a", "aa", "aaa"] + # a.uniq! {|element| element.size } # => nil # - # Returns `nil` if no elements removed. + # Related: see [Methods for Deleting](rdoc-ref:Array@Methods+for+Deleting). # def uniq!: () -> self? | () { (Elem) -> untyped } -> self? # # Prepends the given `objects` to `self`: # # a = [:foo, 'bar', 2] # a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] # - # Related: #push, #pop, #shift. + # Related: Array#shift; see also [Methods for + # Assigning](rdoc-ref:Array@Methods+for+Assigning). # def unshift: (*Elem obj) -> self # - # Returns a new Array whose elements are the elements of `self` at the given - # Integer or Range `indexes`. + # Returns elements from `self` in a new array; does not modify `self`. # - # For each positive `index`, returns the element at offset `index`: + # The objects included in the returned array are the elements of `self` selected + # by the given `specifiers`, each of which must be a numeric index or a Range. # - # a = [:foo, 'bar', 2] - # a.values_at(0, 2) # => [:foo, 2] - # a.values_at(0..1) # => [:foo, "bar"] + # In brief: # - # The given `indexes` may be in any order, and may repeat: + # a = ['a', 'b', 'c', 'd'] # - # a = [:foo, 'bar', 2] - # a.values_at(2, 0, 1, 0, 2) # => [2, :foo, "bar", :foo, 2] - # a.values_at(1, 0..2) # => ["bar", :foo, "bar", 2] + # # Index specifiers. + # a.values_at(2, 0, 2, 0) # => ["c", "a", "c", "a"] # May repeat. + # a.values_at(-4, -3, -2, -1) # => ["a", "b", "c", "d"] # Counts backwards if negative. + # a.values_at(-50, 50) # => [nil, nil] # Outside of self. # - # Assigns `nil` for an `index` that is too large: + # # Range specifiers. + # a.values_at(1..3) # => ["b", "c", "d"] # From range.begin to range.end. + # a.values_at(1...3) # => ["b", "c"] # End excluded. + # a.values_at(3..1) # => [] # No such elements. # - # a = [:foo, 'bar', 2] - # a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil] + # a.values_at(-3..3) # => ["b", "c", "d"] # Negative range.begin counts backwards. + # a.values_at(-50..3) # Raises RangeError. # - # Returns a new empty Array if no arguments given. + # a.values_at(1..-2) # => ["b", "c"] # Negative range.end counts backwards. + # a.values_at(1..-50) # => [] # No such elements. # - # For each negative `index`, counts backward from the end of the array: + # # Mixture of specifiers. + # a.values_at(2..3, 3, 0..1, 0) # => ["c", "d", "d", "a", "b", "a"] # - # a = [:foo, 'bar', 2] - # a.values_at(-1, -3) # => [2, :foo] + # With no `specifiers` given, returns a new empty array: + # + # a = ['a', 'b', 'c', 'd'] + # a.values_at # => [] # - # Assigns `nil` for an `index` that is too small: + # For each numeric specifier `index`, includes an element: # - # a = [:foo, 'bar', 2] - # a.values_at(0, -5, 1, -6, 2) # => [:foo, nil, "bar", nil, 2] + # * For each non-negative numeric specifier `index` that is in-range (less + # than `self.size`), includes the element at offset `index`: # - # The given `indexes` may have a mixture of signs: + # a.values_at(0, 2) # => ["a", "c"] + # a.values_at(0.1, 2.9) # => ["a", "c"] # - # a = [:foo, 'bar', 2] - # a.values_at(0, -2, 1, -1) # => [:foo, "bar", "bar", 2] + # * For each negative numeric `index` that is in-range (greater than or equal + # to `- self.size`), counts backwards from the end of `self`: + # + # a.values_at(-1, -4) # => ["d", "a"] + # + # The given indexes may be in any order, and may repeat: + # + # a.values_at(2, 0, 1, 0, 2) # => ["c", "a", "b", "a", "c"] + # + # For each `index` that is out-of-range, includes `nil`: + # + # a.values_at(4, -5) # => [nil, nil] + # + # For each Range specifier `range`, includes elements according to `range.begin` + # and `range.end`: + # + # * If both `range.begin` and `range.end` are non-negative and in-range (less + # than `self.size`), includes elements from index `range.begin` through + # `range.end - 1` (if `range.exclude_end?`), or through `range.end` + # (otherwise): + # + # a.values_at(1..2) # => ["b", "c"] + # a.values_at(1...2) # => ["b"] + # + # * If `range.begin` is negative and in-range (greater than or equal to `- + # self.size`), counts backwards from the end of `self`: + # + # a.values_at(-2..3) # => ["c", "d"] + # + # * If `range.begin` is negative and out-of-range, raises an exception: + # + # a.values_at(-5..3) # Raises RangeError. + # + # * If `range.end` is positive and out-of-range, extends the returned array + # with `nil` elements: + # + # a.values_at(1..5) # => ["b", "c", "d", nil, nil] + # + # * If `range.end` is negative and in-range, counts backwards from the end of + # `self`: + # + # a.values_at(1..-2) # => ["b", "c"] + # + # * If `range.end` is negative and out-of-range, returns an empty array: + # + # a.values_at(1..-5) # => [] + # + # The given ranges may be in any order and may repeat: + # + # a.values_at(2..3, 0..1, 2..3) # => ["c", "d", "a", "b", "c", "d"] + # + # The given specifiers may be any mixture of indexes and ranges: + # + # a.values_at(3, 1..2, 0, 2..3) # => ["d", "b", "c", "a", "c", "d"] + # + # Related: see [Methods for Fetching](rdoc-ref:Array@Methods+for+Fetching). # def values_at: (*int | ::Range[::Integer] selector) -> ::Array[Elem?] # - # When no block given, returns a new Array `new_array` of size `self.size` whose - # elements are Arrays. + # With no block given, combines `self` with the collection of `other_arrays`; + # returns a new array of sub-arrays: + # + # [0, 1].zip(['zero', 'one'], [:zero, :one]) + # # => [[0, "zero", :zero], [1, "one", :one]] + # + # Returned: + # + # * The outer array is of size `self.size`. + # * Each sub-array is of size `other_arrays.size + 1`. + # * The *nth* sub-array contains (in order): + # + # * The *nth* element of `self`. + # * The *nth* element of each of the other arrays, as available. # - # Each nested array `new_array[n]` is of size `other_arrays.size+1`, and - # contains: + # Example: # - # * The *nth* element of `self`. - # * The *nth* element of each of the `other_arrays`. + # a = [0, 1] + # zipped = a.zip(['zero', 'one'], [:zero, :one]) + # # => [[0, "zero", :zero], [1, "one", :one]] + # zipped.size # => 2 # Same size as a. + # zipped.first.size # => 3 # Size of other arrays plus 1. # - # If all `other_arrays` and `self` are the same size: + # When the other arrays are all the same size as `self`, the returned sub-arrays + # are a rearrangement containing exactly elements of all the arrays (including + # `self`), with no omissions or additions: # # a = [:a0, :a1, :a2, :a3] # b = [:b0, :b1, :b2, :b3] # c = [:c0, :c1, :c2, :c3] # d = a.zip(b, c) - # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] + # pp d + # # => + # [[:a0, :b0, :c0], + # [:a1, :b1, :c1], + # [:a2, :b2, :c2], + # [:a3, :b3, :c3]] # - # If any array in `other_arrays` is smaller than `self`, fills to `self.size` - # with `nil`: + # When one of the other arrays is smaller than `self`, pads the corresponding + # sub-array with `nil` elements: # # a = [:a0, :a1, :a2, :a3] # b = [:b0, :b1, :b2] # c = [:c0, :c1] # d = a.zip(b, c) - # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, nil], [:a3, nil, nil]] + # pp d + # # => + # [[:a0, :b0, :c0], + # [:a1, :b1, :c1], + # [:a2, :b2, nil], + # [:a3, nil, nil]] # - # If any array in `other_arrays` is larger than `self`, its trailing elements - # are ignored: + # When one of the other arrays is larger than `self`, *ignores* its trailing + # elements: # # a = [:a0, :a1, :a2, :a3] # b = [:b0, :b1, :b2, :b3, :b4] # c = [:c0, :c1, :c2, :c3, :c4, :c5] # d = a.zip(b, c) - # d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] + # pp d + # # => + # [[:a0, :b0, :c0], + # [:a1, :b1, :c1], + # [:a2, :b2, :c2], + # [:a3, :b3, :c3]] # - # When a block is given, calls the block with each of the sub-arrays (formed as - # above); returns `nil`: + # With a block given, calls the block with each of the other arrays; returns + # `nil`: # + # d = [] # a = [:a0, :a1, :a2, :a3] # b = [:b0, :b1, :b2, :b3] # c = [:c0, :c1, :c2, :c3] - # a.zip(b, c) {|sub_array| p sub_array} # => nil + # a.zip(b, c) {|sub_array| d.push(sub_array.reverse) } # => nil + # pp d + # # => + # [[:c0, :b0, :a0], + # [:c1, :b1, :a1], + # [:c2, :b2, :a2], + # [:c3, :b3, :a3]] # - # Output: + # For an **object** in **other_arrays** that is not actually an array, forms the + # the "other array" as `object.to_ary`, if defined, or as `object.each.to_a` + # otherwise. # - # [:a0, :b0, :c0] - # [:a1, :b1, :c1] - # [:a2, :b2, :c2] - # [:a3, :b3, :c3] + # Related: see [Methods for Converting](rdoc-ref:Array@Methods+for+Converting). # def zip: [U] (_Each[U] arg) -> Array[[ Elem, U? ]] | (_Each[untyped] arg, *_Each[untyped] args) -> Array[Array[untyped]] @@ -3834,16 +3981,16 @@ class Array[unchecked out Elem] < Object # - # Returns the union of `array` and Array `other_array`; duplicates are removed; - # order is preserved; items are compared using `eql?`: + # Returns the union of `self` and `other_array`; duplicates are removed; order + # is preserved; items are compared using `eql?`: # # [0, 1] | [2, 3] # => [0, 1, 2, 3] # [0, 1, 1] | [2, 2, 3] # => [0, 1, 2, 3] # [0, 1, 2] | [3, 2, 1, 0] # => [0, 1, 2, 3] # - # Related: Array#union. + # Related: see [Methods for Combining](rdoc-ref:Array@Methods+for+Combining). # def |: [T] (::Array[T] other_ary) -> ::Array[Elem | T] @@ -3851,13 +3998,18 @@ class Array[unchecked out Elem] < Object # - # Replaces the content of `self` with the content of `other_array`; returns + # Replaces the elements of `self` with the elements of `other_array`, which must + # be an [array-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects); returns # `self`: # - # a = [:foo, 'bar', 2] - # a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3] + # a = ['a', 'b', 'c'] # => ["a", "b", "c"] + # a.replace(['d', 'e']) # => ["d", "e"] + # + # Related: see [Methods for Assigning](rdoc-ref:Array@Methods+for+Assigning). # def initialize_copy: (self other_ary) -> void end diff --git a/core/basic_object.rbs b/core/basic_object.rbs index 49c9a3cb1c..ce7deb01f5 100644 --- a/core/basic_object.rbs +++ b/core/basic_object.rbs @@ -1,49 +1,44 @@ # -# BasicObject is the parent class of all classes in Ruby. It's an explicit -# blank class. +# `BasicObject` is the parent class of all classes in Ruby. In particular, +# `BasicObject` is the parent class of class Object, which is itself the default +# parent class of every Ruby class: # -# BasicObject can be used for creating object hierarchies independent of Ruby's -# object hierarchy, proxy objects like the Delegator class, or other uses where -# namespace pollution from Ruby's methods and classes must be avoided. +# class Foo; end +# Foo.superclass # => Object +# Object.superclass # => BasicObject # -# To avoid polluting BasicObject for other users an appropriately named subclass -# of BasicObject should be created instead of directly modifying BasicObject: +# `BasicObject` is the only class that has no parent: # -# class MyObjectSystem < BasicObject -# end +# BasicObject.superclass # => nil # -# BasicObject does not include Kernel (for methods like `puts`) and BasicObject -# is outside of the namespace of the standard library so common classes will not -# be found without using a full class path. +# Class `BasicObject` can be used to create an object hierarchy (e.g., class +# Delegator) that is independent of Ruby's object hierarchy. Such objects: # -# A variety of strategies can be used to provide useful portions of the standard -# library to subclasses of BasicObject. A subclass could `include Kernel` to -# obtain `puts`, `exit`, etc. A custom Kernel-like module could be created and -# included or delegation can be used via #method_missing: +# * Do not have namespace "pollution" from the many methods provided in class +# Object and its included module Kernel. +# * Do not have definitions of common classes, and so references to such +# common classes must be fully qualified (`::String`, not `String`). # -# class MyObjectSystem < BasicObject -# DELEGATE = [:puts, :p] +# A variety of strategies can be used to provide useful portions of the Standard +# Library in subclasses of `BasicObject`: # -# def method_missing(name, *args, &block) -# return super unless DELEGATE.include? name -# ::Kernel.send(name, *args, &block) -# end +# * The immediate subclass could `include Kernel`, which would define methods +# such as `puts`, `exit`, etc. +# * A custom Kernel-like module could be created and included. +# * Delegation can be used via #method_missing: # -# def respond_to_missing?(name, include_private = false) -# DELEGATE.include?(name) or super -# end -# end +# class MyObjectSystem < BasicObject +# DELEGATE = [:puts, :p] # -# Access to classes and modules from the Ruby standard library can be obtained -# in a BasicObject subclass by referencing the desired constant from the root -# like `::File` or `::Enumerator`. Like #method_missing, #const_missing can be -# used to delegate constant lookup to `Object`: +# def method_missing(name, *args, &block) +# return super unless DELEGATE.include? name +# ::Kernel.send(name, *args, &block) +# end # -# class MyObjectSystem < BasicObject -# def self.const_missing(name) -# ::Object.const_get(name) -# end -# end +# def respond_to_missing?(name, include_private = false) +# DELEGATE.include?(name) +# end +# end # # ### What's Here # @@ -60,6 +55,14 @@ # `self`. # * #instance_exec: Executes the given block in the context of `self`, passing # the given arguments. +# * #method_missing: Called when `self` is called with a method it does not +# define. +# * #singleton_method_added: Called when a singleton method is added to +# `self`. +# * #singleton_method_removed: Called when a singleton method is removed from +# `self`. +# * #singleton_method_undefined: Called when a singleton method is undefined +# in `self`. # class BasicObject # # 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.rect(2, 3) * Complex.rect(2, 3) # => (-5+12i) + # Complex.rect(900) * Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i) + # Complex.rect(9, 8) * 4 # => (36+32i) + # Complex.rect(20, 9) * 9.8 # => (196.0+88.2i) # def *: (Numeric) -> Complex @@ -124,8 +202,8 @@ class Complex < Numeric # --> # Returns `self` raised to power `numeric`: # - # Complex('i') ** 2 # => (-1+0i) - # Complex(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i) + # Complex.rect(0, 1) ** 2 # => (-1+0i) + # Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i) # def **: (Numeric) -> Complex @@ -135,11 +213,11 @@ class Complex < Numeric # --> # 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.rect(2, 3) + Complex.rect(2, 3) # => (4+6i) + # Complex.rect(900) + Complex.rect(1) # => (901+0i) + # Complex.rect(-2, 9) + Complex.rect(-9, 2) # => (-11+11i) + # Complex.rect(9, 8) + 4 # => (13+8i) + # Complex.rect(20, 9) + 9.8 # => (29.8+9i) # def +: (Numeric) -> Complex @@ -151,11 +229,11 @@ class Complex < Numeric # --> # 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.rect(2, 3) - Complex.rect(2, 3) # => (0+0i) + # Complex.rect(900) - Complex.rect(1) # => (899+0i) + # Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i) + # Complex.rect(9, 8) - 4 # => (5+8i) + # Complex.rect(20, 9) - 9.8 # => (10.2+9i) # def -: (Numeric) -> Complex @@ -165,8 +243,8 @@ class Complex < Numeric # --> # 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.rect(1, 2) # => (-1-2i) + # -Complex.rect(-1, -2) # => (1+2i) # def -@: () -> Complex @@ -176,11 +254,11 @@ class Complex < Numeric # --> # 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.rect(2, 3) / Complex.rect(2, 3) # => (1+0i) + # Complex.rect(900) / Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i) + # Complex.rect(9, 8) / 4 # => ((9/4)+2i) + # Complex.rect(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def /: (Numeric) -> Complex @@ -204,12 +282,12 @@ class Complex < Numeric # # 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. + # Complex.rect(2) <=> 3 # => -1 + # Complex.rect(2) <=> 2 # => 0 + # Complex.rect(2) <=> 1 # => 1 + # Complex.rect(2, 1) <=> 1 # => nil # self.imag not zero. + # Complex.rect(1) <=> Complex.rect(1, 1) # => nil # object.imag not zero. + # Complex.rect(1) <=> 'Foo' # => nil # object.imag not defined. # def <=>: (untyped) -> Integer? @@ -219,7 +297,7 @@ class Complex < Numeric # --> # Returns `true` if `self.real == object.real` and `self.imag == object.imag`: # - # Complex(2, 3) == Complex(2.0, 3.0) # => true + # Complex.rect(2, 3) == Complex.rect(2.0, 3.0) # => true # def ==: (untyped) -> bool @@ -341,9 +419,9 @@ class Complex < Numeric # rdoc-file=complex.c # - fdiv(numeric) -> new_complex # --> - # Returns `Complex(self.real/numeric, self.imag/numeric)`: + # Returns `Complex.rect(self.real/numeric, self.imag/numeric)`: # - # Complex(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i) + # Complex.rect(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i) # def fdiv: (Numeric) -> Complex @@ -354,8 +432,8 @@ class Complex < Numeric # 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 + # Complex.rect(1, 1).finite? # => true + # Complex.rect(Float::INFINITY, 0).finite? # => false # # Related: Numeric#finite?, Float#finite?. # @@ -372,7 +450,7 @@ class Complex < Numeric # 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 + # Complex.rect(1, 2).hash == Complex.rect(1, 2).hash # => true # def hash: () -> Integer @@ -381,8 +459,8 @@ class Complex < Numeric # # Returns the imaginary value for `self`: # - # Complex(7).imaginary #=> 0 - # Complex(9, -4).imaginary #=> -4 + # Complex.rect(7).imag # => 0 + # Complex.rect(9, -4).imag # => -4 # # If `self` was created with [polar # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is @@ -398,8 +476,8 @@ class Complex < Numeric # --> # Returns the imaginary value for `self`: # - # Complex(7).imaginary #=> 0 - # Complex(9, -4).imaginary #=> -4 + # Complex.rect(7).imag # => 0 + # Complex.rect(9, -4).imag # => -4 # # If `self` was created with [polar # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is @@ -416,8 +494,8 @@ class Complex < Numeric # Returns `1` if either `self.real.infinite?` or `self.imag.infinite?` is true, # `nil` otherwise: # - # Complex(Float::INFINITY, 0).infinite? # => 1 - # Complex(1, 1).infinite? # => nil + # Complex.rect(Float::INFINITY, 0).infinite? # => 1 + # Complex.rect(1, 1).infinite? # => nil # # Related: Numeric#infinite?, Float#infinite?. # @@ -429,11 +507,11 @@ class Complex < Numeric # --> # 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.rect(2).inspect # => "(2+0i)" + # Complex.rect(-8, 6).inspect # => "(-8+6i)" + # Complex.rect(0, Rational(1, 2)).inspect # => "(0+(1/2)*i)" + # Complex.rect(0, Float::INFINITY).inspect # => "(0+Infinity*i)" + # Complex.rect(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)" # def inspect: () -> String @@ -468,13 +546,13 @@ class Complex < Numeric # denominator](https://en.wikipedia.org/wiki/Lowest_common_denominator) of the # two: # - # c = Complex(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i) - # c.numerator # => (8+9i) + # c = Complex.rect(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i) + # c.numerator # => (8+9i) # # 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)`. + # `c.numerator` is `Complex.rect(8, 9)`. # # Related: Complex#denominator. # @@ -520,11 +598,11 @@ class Complex < Numeric # --> # 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.rect(2, 3) / Complex.rect(2, 3) # => (1+0i) + # Complex.rect(900) / Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i) + # Complex.rect(9, 8) / 4 # => ((9/4)+2i) + # Complex.rect(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def quo: (Numeric) -> Complex @@ -538,24 +616,24 @@ class Complex < Numeric # 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.rect(1, 0).rationalize # => (1/1) + # Complex.rect(1, Rational(0, 1)).rationalize # => (1/1) + # Complex.rect(3.14159, 0).rationalize # => (314159/100000) # # With argument `epsilon` given, returns a Rational object whose value is # exactly or approximately equal to that of `self.real` to the given precision: # - # 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) + # Complex.rect(3.14159, 0).rationalize(0.1) # => (16/5) + # Complex.rect(3.14159, 0).rationalize(0.01) # => (22/7) + # Complex.rect(3.14159, 0).rationalize(0.001) # => (201/64) + # Complex.rect(3.14159, 0).rationalize(0.0001) # => (333/106) + # Complex.rect(3.14159, 0).rationalize(0.00001) # => (355/113) + # Complex.rect(3.14159, 0).rationalize(0.000001) # => (7433/2366) + # Complex.rect(3.14159, 0).rationalize(0.0000001) # => (9208/2931) + # Complex.rect(3.14159, 0).rationalize(0.00000001) # => (47460/15107) + # Complex.rect(3.14159, 0).rationalize(0.000000001) # => (76149/24239) + # Complex.rect(3.14159, 0).rationalize(0.0000000001) # => (314159/100000) + # Complex.rect(3.14159, 0).rationalize(0.0) # => (3537115888337719/1125899906842624) # # Related: Complex#to_r. # @@ -567,8 +645,8 @@ class Complex < Numeric # --> # Returns the real value for `self`: # - # Complex(7).real #=> 7 - # Complex(9, -4).real #=> 9 + # Complex.rect(7).real # => 7 + # Complex.rect(9, -4).real # => 9 # # If `self` was created with [polar # coordinates](rdoc-ref:Complex@Polar+Coordinates), the returned value is @@ -640,8 +718,8 @@ class Complex < Numeric # --> # 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.rect(1, 0).to_f # => 1.0 + # Complex.rect(1, Rational(0, 1)).to_f # => 1.0 # # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or # `Rational(0, *n*)`). @@ -654,8 +732,8 @@ class Complex < Numeric # --> # Returns the value of `self.real` as an Integer, if possible: # - # Complex(1, 0).to_i # => 1 - # Complex(1, Rational(0, 1)).to_i # => 1 + # Complex.rect(1, 0).to_i # => 1 + # Complex.rect(1, Rational(0, 1)).to_i # => 1 # # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or # `Rational(0, *n*)`). @@ -670,11 +748,12 @@ class Complex < Numeric # --> # 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.rect(1, 0).to_r # => (1/1) + # Complex.rect(1, Rational(0, 1)).to_r # => (1/1) + # Complex.rect(1, 0.0).to_r # => (1/1) # # Raises RangeError if `self.imag` is not exactly zero (either `Integer(0)` or - # `Rational(0, *n*)`). + # `Rational(0, *n*)`) and `self.imag.to_r` is not exactly zero. # # Related: Complex#rationalize. # @@ -686,11 +765,11 @@ class Complex < Numeric # --> # 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.rect(2).to_s # => "2+0i" + # Complex.rect(-8, 6).to_s # => "-8+6i" + # Complex.rect(0, Rational(1, 2)).to_s # => "0+1/2i" + # Complex.rect(0, Float::INFINITY).to_s # => "0+Infinity*i" + # Complex.rect(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i" # def to_s: () -> String @@ -700,7 +779,7 @@ class Complex < Numeric end # -# Equivalent to `Complex(0, 1)`: +# Equivalent to `Complex.rect(0, 1)`: # # Complex::I # => (0+1i) # diff --git a/core/data.rbs b/core/data.rbs index d0786616de..ed7734eae4 100644 --- a/core/data.rbs +++ b/core/data.rbs @@ -83,7 +83,7 @@ class Data # #=> # # # Note that member-less Data is acceptable and might be a useful technique for - # defining several homogenous data classes, like + # defining several homogeneous data classes, like # # class HTTPFetcher # Response = Data.define(:body) diff --git a/core/dir.rbs b/core/dir.rbs index e414c8bd12..c10eb90819 100644 --- a/core/dir.rbs +++ b/core/dir.rbs @@ -654,7 +654,7 @@ class Dir # rdoc-file=dir.c # - Dir.home(user_name = nil) -> dirpath # --> - # Retruns the home directory path of the user specified with `user_name` if it + # Returns the home directory path of the user specified with `user_name` if it # is not `nil`, or the current login user: # # Dir.home # => "/home/me" diff --git a/core/enumerable.rbs b/core/enumerable.rbs index 774cdcad18..e0368f5c6b 100644 --- a/core/enumerable.rbs +++ b/core/enumerable.rbs @@ -16,8 +16,8 @@ # These methods return information about the Enumerable other than the elements # themselves: # -# * #include?, #member?: Returns `true` if `self == object`, `false` -# otherwise. +# * #member? (aliased as #include?): Returns `true` if `self == object`, +# `false` otherwise. # * #all?: Returns `true` if all elements meet a specified criterion; `false` # otherwise. # * #any?: Returns `true` if any element meets a specified criterion; `false` @@ -37,7 +37,7 @@ # # *Leading, trailing, or all elements*: # -# * #entries, #to_a: Returns all elements. +# * #to_a (aliased as #entries): Returns all elements. # * #first: Returns the first element or leading elements. # * #take: Returns a specified number of leading elements. # * #drop: Returns a specified number of trailing elements. @@ -47,9 +47,9 @@ # *Minimum and maximum value elements*: # # * #min: Returns the elements whose values are smallest among the elements, -# as determined by `<=>` or a given block. +# as determined by `#<=>` or a given block. # * #max: Returns the elements whose values are largest among the elements, as -# determined by `<=>` or a given block. +# determined by `#<=>` or a given block. # * #minmax: Returns a 2-element Array containing the smallest and largest # elements. # * #min_by: Returns the smallest element, as determined by the given block. @@ -77,8 +77,9 @@ # # These methods return elements that meet a specified criterion: # -# * #find, #detect: Returns an element selected by the block. -# * #find_all, #filter, #select: Returns elements selected by the block. +# * #find (aliased as #detect): Returns an element selected by the block. +# * #find_all (aliased as #filter, #select): Returns elements selected by the +# block. # * #find_index: Returns the index of an element selected by a given object or # block. # * #reject: Returns elements not rejected by the block. @@ -88,7 +89,7 @@ # # These methods return elements in sorted order: # -# * #sort: Returns the elements, sorted by `<=>` or the given block. +# * #sort: Returns the elements, sorted by `#<=>` or the given block. # * #sort_by: Returns the elements, sorted by the given block. # # ### Methods for Iterating @@ -107,15 +108,16 @@ # # ### Other Methods # -# * #map, #collect: Returns objects returned by the block. +# * #collect (aliased as #map): Returns objects returned by the block. # * #filter_map: Returns truthy objects returned by the block. -# * #flat_map, #collect_concat: Returns flattened objects returned by the -# block. +# * #flat_map (aliased as #collect_concat): Returns flattened objects returned +# by the block. # * #grep: Returns elements selected by a given object or objects returned by # a given block. # * #grep_v: Returns elements selected by a given object or objects returned # by a given block. -# * #reduce, #inject: Returns the object formed by combining all elements. +# * #inject (aliased as #reduce): Returns the object formed by combining all +# elements. # * #sum: Returns the sum of the elements, using method `+`. # * #zip: Combines each element with elements from other enumerables; returns # the n-tuples or calls the block with each. @@ -466,8 +468,8 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # - each_with_index(*args) {|element, i| ..... } -> self # - each_with_index(*args) -> enumerator # --> - # With a block given, calls the block with each element and its index; returns - # `self`: + # Invoke `self.each` with `*args`. With a block given, the block receives each + # element and its index; returns `self`: # # h = {} # (1..4).each_with_index {|element, i| h[element] = i } # => 1..4 @@ -720,147 +722,155 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # - # Returns an object formed from operands via either: + # Returns the result of applying a reducer to an initial value and the first + # element of the Enumerable. It then takes the result and applies the function + # to it and the second element of the collection, and so on. The return value is + # the result returned by the final call to the function. # - # * A method named by `symbol`. - # * A block to which each operand is passed. + # You can think of # - # With method-name argument `symbol`, combines operands using the method: + # [ a, b, c, d ].inject(i) { |r, v| fn(r, v) } # - # # Sum, without initial_operand. - # (1..4).inject(:+) # => 10 - # # Sum, with initial_operand. - # (1..4).inject(10, :+) # => 20 + # as being # - # With a block, passes each operand to the block: + # fn(fn(fn(fn(i, a), b), c), d) # - # # Sum of squares, without initial_operand. - # (1..4).inject {|sum, n| sum + n*n } # => 30 - # # Sum of squares, with initial_operand. - # (1..4).inject(2) {|sum, n| sum + n*n } # => 32 + # In a way the `inject` function *injects* the function between the elements of + # the enumerable. # - # **Operands** + # `inject` is aliased as `reduce`. You use it when you want to *reduce* a + # collection to a single value. # - # If argument `initial_operand` is not given, the operands for `inject` are - # simply the elements of `self`. Example calls and their operands: + # **The Calling Sequences** # - # `(1..4).inject(:+)` - # : `[1, 2, 3, 4]`. + # Let's start with the most verbose: # - # `(1...4).inject(:+)` - # : `[1, 2, 3]`. + # enum.inject(initial_value) do |result, next_value| + # # do something with +result+ and +next_value+ + # # the value returned by the block becomes the + # # value passed in to the next iteration + # # as +result+ + # end # - # `('a'..'d').inject(:+)` - # : `['a', 'b', 'c', 'd']`. + # For example: # - # `('a'...'d').inject(:+)` - # : `['a', 'b', 'c']`. + # product = [ 2, 3, 4 ].inject(1) do |result, next_value| + # result * next_value + # end + # product #=> 24 # + # When this runs, the block is first called with `1` (the initial value) and `2` + # (the first element of the array). The block returns `1*2`, so on the next + # iteration the block is called with `2` (the previous result) and `3`. The + # block returns `6`, and is called one last time with `6` and `4`. The result of + # the block, `24` becomes the value returned by `inject`. This code returns the + # product of the elements in the enumerable. # - # Examples with first operand (which is `self.first`) of various types: + # **First Shortcut: Default Initial value** # - # # Integer. - # (1..4).inject(:+) # => 10 - # # Float. - # [1.0, 2, 3, 4].inject(:+) # => 10.0 - # # Character. - # ('a'..'d').inject(:+) # => "abcd" - # # Complex. - # [Complex(1, 2), 3, 4].inject(:+) # => (8+2i) + # In the case of the previous example, the initial value, `1`, wasn't really + # necessary: the calculation of the product of a list of numbers is + # self-contained. # - # If argument `initial_operand` is given, the operands for `inject` are that - # value plus the elements of `self`. Example calls their operands: + # In these circumstances, you can omit the `initial_value` parameter. `inject` + # will then initially call the block with the first element of the collection as + # the `result` parameter and the second element as the `next_value`. # - # `(1..4).inject(10, :+)` - # : `[10, 1, 2, 3, 4]`. + # [ 2, 3, 4 ].inject do |result, next_value| + # result * next_value + # end # - # `(1...4).inject(10, :+)` - # : `[10, 1, 2, 3]`. + # This shortcut is convenient, but can only be used when the block produces a + # result which can be passed back to it as a first parameter. # - # `('a'..'d').inject('e', :+)` - # : `['e', 'a', 'b', 'c', 'd']`. + # Here's an example where that's not the case: it returns a hash where the keys + # are words and the values are the number of occurrences of that word in the + # enumerable. # - # `('a'...'d').inject('e', :+)` - # : `['e', 'a', 'b', 'c']`. + # freqs = File.read("README.md") + # .scan(/\w{2,}/) + # .reduce(Hash.new(0)) do |counts, word| + # counts[word] += 1 + # counts + # end + # freqs #=> {"Actions"=>4, + # "Status"=>5, + # "MinGW"=>3, + # "https"=>27, + # "github"=>10, + # "com"=>15, ... # + # Note that the last line of the block is just the word `counts`. This ensures + # the return value of the block is the result that's being calculated. # - # Examples with `initial_operand` of various types: + # **Second Shortcut: a Reducer function** # - # # Integer. - # (1..4).inject(2, :+) # => 12 - # # Float. - # (1..4).inject(2.0, :+) # => 12.0 - # # String. - # ('a'..'d').inject('foo', :+) # => "fooabcd" - # # Array. - # %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"] - # # Complex. - # (1..4).inject(Complex(2, 2), :+) # => (12+2i) + # A *reducer function* is a function that takes a partial result and the next + # value, returning the next partial result. The block that is given to `inject` + # is a reducer. # - # **Combination by Given \Method** + # You can also write a reducer as a function and pass the name of that function + # (as a symbol) to `inject`. However, for this to work, the function # - # If the method-name argument `symbol` is given, the operands are combined by - # that method: + # 1. Must be defined on the type of the result value + # 2. Must accept a single parameter, the next value in the collection, and + # 3. Must return an updated result which will also implement the function. # - # * The first and second operands are combined. - # * That result is combined with the third operand. - # * That result is combined with the fourth operand. - # * And so on. + # Here's an example that adds elements to a string. The two calls invoke the + # functions String#concat and String#+ on the result so far, passing it the next + # value. # - # The return value from `inject` is the result of the last combination. + # s = [ "cat", " ", "dog" ].inject("", :concat) + # s #=> "cat dog" + # s = [ "cat", " ", "dog" ].inject("The result is:", :+) + # s #=> "The result is: cat dog" # - # This call to `inject` computes the sum of the operands: + # Here's a more complex example when the result object maintains state of a + # different type to the enumerable elements. # - # (1..4).inject(:+) # => 10 + # class Turtle # - # Examples with various methods: + # def initialize + # @x = @y = 0 + # end # - # # Integer addition. - # (1..4).inject(:+) # => 10 - # # Integer multiplication. - # (1..4).inject(:*) # => 24 - # # Character range concatenation. - # ('a'..'d').inject('', :+) # => "abcd" - # # String array concatenation. - # %w[foo bar baz].inject('', :+) # => "foobarbaz" - # # Hash update. - # h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update) - # h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3} - # # Hash conversion to nested arrays. - # h = {foo: 0, bar: 1}.inject([], :push) - # h # => [[:foo, 0], [:bar, 1]] + # def move(dir) + # case dir + # when "n" then @y += 1 + # when "s" then @y -= 1 + # when "e" then @x += 1 + # when "w" then @x -= 1 + # end + # self + # end + # end # - # **Combination by Given Block** + # position = "nnneesw".chars.reduce(Turtle.new, :move) + # position #=>> # # - # If a block is given, the operands are passed to the block: + # **Third Shortcut: Reducer With no Initial Value** # - # * The first call passes the first and second operands. - # * The second call passes the result of the first call, along with the third - # operand. - # * The third call passes the result of the second call, along with the fourth - # operand. - # * And so on. + # If your reducer returns a value that it can accept as a parameter, then you + # don't have to pass in an initial value. Here `:*` is the name of the *times* + # function: # - # The return value from `inject` is the return value from the last block call. + # product = [ 2, 3, 4 ].inject(:*) + # product # => 24 # - # This call to `inject` gives a block that writes the memo and element, and also - # sums the elements: + # String concatenation again: # - # (1..4).inject do |memo, element| - # p "Memo: #{memo}; element: #{element}" - # memo + element - # end # => 10 + # s = [ "cat", " ", "dog" ].inject(:+) + # s #=> "cat dog" # - # Output: + # And an example that converts a hash to an array of two-element subarrays. # - # "Memo: 1; element: 2" - # "Memo: 3; element: 3" - # "Memo: 6; element: 4" + # nested = {foo: 0, bar: 1}.inject([], :push) + # nested # => [[:foo, 0], [:bar, 1]] # def inject: (untyped init, Symbol method) -> untyped | (Symbol method) -> untyped @@ -878,7 +888,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # The ordering of equal elements is indeterminate and may be unstable. # # With no argument and no block, returns the maximum element, using the - # elements' own method `<=>` for comparison: + # elements' own method `#<=>` for comparison: # # (1..4).max # => 4 # (-4..-1).max # => -1 @@ -976,7 +986,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # The ordering of equal elements is indeterminate and may be unstable. # # With no argument and no block, returns the minimum element, using the - # elements' own method `<=>` for comparison: + # elements' own method `#<=>` for comparison: # # (1..4).min # => 1 # (-4..-1).min # => -4 @@ -1073,7 +1083,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # indeterminate and may be unstable. # # With no argument and no block, returns the minimum and maximum elements, using - # the elements' own method `<=>` for comparison: + # the elements' own method `#<=>` for comparison: # # (1..4).minmax # => [1, 4] # (-4..-1).minmax # => [-4, -1] @@ -1287,7 +1297,7 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # Returns an array containing the sorted elements of `self`. The ordering of # equal elements is indeterminate and may be unstable. # - # With no block given, the sort compares using the elements' own method `<=>`: + # With no block given, the sort compares using the elements' own method `#<=>`: # # %w[b c a d].sort # => ["a", "b", "c", "d"] # {foo: 0, bar: 1, baz: 2}.sort # => [[:bar, 1], [:baz, 2], [:foo, 0]] @@ -1555,142 +1565,150 @@ module Enumerable[unchecked out Elem] : _Each[Elem] def member?: (Elem arg0) -> bool # - # Returns an object formed from operands via either: + # Returns the result of applying a reducer to an initial value and the first + # element of the Enumerable. It then takes the result and applies the function + # to it and the second element of the collection, and so on. The return value is + # the result returned by the final call to the function. # - # * A method named by `symbol`. - # * A block to which each operand is passed. + # You can think of # - # With method-name argument `symbol`, combines operands using the method: + # [ a, b, c, d ].inject(i) { |r, v| fn(r, v) } # - # # Sum, without initial_operand. - # (1..4).inject(:+) # => 10 - # # Sum, with initial_operand. - # (1..4).inject(10, :+) # => 20 + # as being # - # With a block, passes each operand to the block: + # fn(fn(fn(fn(i, a), b), c), d) # - # # Sum of squares, without initial_operand. - # (1..4).inject {|sum, n| sum + n*n } # => 30 - # # Sum of squares, with initial_operand. - # (1..4).inject(2) {|sum, n| sum + n*n } # => 32 + # In a way the `inject` function *injects* the function between the elements of + # the enumerable. # - # **Operands** + # `inject` is aliased as `reduce`. You use it when you want to *reduce* a + # collection to a single value. # - # If argument `initial_operand` is not given, the operands for `inject` are - # simply the elements of `self`. Example calls and their operands: + # **The Calling Sequences** # - # `(1..4).inject(:+)` - # : `[1, 2, 3, 4]`. + # Let's start with the most verbose: # - # `(1...4).inject(:+)` - # : `[1, 2, 3]`. + # enum.inject(initial_value) do |result, next_value| + # # do something with +result+ and +next_value+ + # # the value returned by the block becomes the + # # value passed in to the next iteration + # # as +result+ + # end # - # `('a'..'d').inject(:+)` - # : `['a', 'b', 'c', 'd']`. + # For example: # - # `('a'...'d').inject(:+)` - # : `['a', 'b', 'c']`. + # product = [ 2, 3, 4 ].inject(1) do |result, next_value| + # result * next_value + # end + # product #=> 24 # + # When this runs, the block is first called with `1` (the initial value) and `2` + # (the first element of the array). The block returns `1*2`, so on the next + # iteration the block is called with `2` (the previous result) and `3`. The + # block returns `6`, and is called one last time with `6` and `4`. The result of + # the block, `24` becomes the value returned by `inject`. This code returns the + # product of the elements in the enumerable. # - # Examples with first operand (which is `self.first`) of various types: + # **First Shortcut: Default Initial value** # - # # Integer. - # (1..4).inject(:+) # => 10 - # # Float. - # [1.0, 2, 3, 4].inject(:+) # => 10.0 - # # Character. - # ('a'..'d').inject(:+) # => "abcd" - # # Complex. - # [Complex(1, 2), 3, 4].inject(:+) # => (8+2i) + # In the case of the previous example, the initial value, `1`, wasn't really + # necessary: the calculation of the product of a list of numbers is + # self-contained. # - # If argument `initial_operand` is given, the operands for `inject` are that - # value plus the elements of `self`. Example calls their operands: + # In these circumstances, you can omit the `initial_value` parameter. `inject` + # will then initially call the block with the first element of the collection as + # the `result` parameter and the second element as the `next_value`. # - # `(1..4).inject(10, :+)` - # : `[10, 1, 2, 3, 4]`. + # [ 2, 3, 4 ].inject do |result, next_value| + # result * next_value + # end # - # `(1...4).inject(10, :+)` - # : `[10, 1, 2, 3]`. + # This shortcut is convenient, but can only be used when the block produces a + # result which can be passed back to it as a first parameter. # - # `('a'..'d').inject('e', :+)` - # : `['e', 'a', 'b', 'c', 'd']`. + # Here's an example where that's not the case: it returns a hash where the keys + # are words and the values are the number of occurrences of that word in the + # enumerable. # - # `('a'...'d').inject('e', :+)` - # : `['e', 'a', 'b', 'c']`. + # freqs = File.read("README.md") + # .scan(/\w{2,}/) + # .reduce(Hash.new(0)) do |counts, word| + # counts[word] += 1 + # counts + # end + # freqs #=> {"Actions"=>4, + # "Status"=>5, + # "MinGW"=>3, + # "https"=>27, + # "github"=>10, + # "com"=>15, ... # + # Note that the last line of the block is just the word `counts`. This ensures + # the return value of the block is the result that's being calculated. # - # Examples with `initial_operand` of various types: + # **Second Shortcut: a Reducer function** # - # # Integer. - # (1..4).inject(2, :+) # => 12 - # # Float. - # (1..4).inject(2.0, :+) # => 12.0 - # # String. - # ('a'..'d').inject('foo', :+) # => "fooabcd" - # # Array. - # %w[a b c].inject(['x'], :push) # => ["x", "a", "b", "c"] - # # Complex. - # (1..4).inject(Complex(2, 2), :+) # => (12+2i) + # A *reducer function* is a function that takes a partial result and the next + # value, returning the next partial result. The block that is given to `inject` + # is a reducer. # - # **Combination by Given \Method** + # You can also write a reducer as a function and pass the name of that function + # (as a symbol) to `inject`. However, for this to work, the function # - # If the method-name argument `symbol` is given, the operands are combined by - # that method: + # 1. Must be defined on the type of the result value + # 2. Must accept a single parameter, the next value in the collection, and + # 3. Must return an updated result which will also implement the function. # - # * The first and second operands are combined. - # * That result is combined with the third operand. - # * That result is combined with the fourth operand. - # * And so on. + # Here's an example that adds elements to a string. The two calls invoke the + # functions String#concat and String#+ on the result so far, passing it the next + # value. # - # The return value from `inject` is the result of the last combination. + # s = [ "cat", " ", "dog" ].inject("", :concat) + # s #=> "cat dog" + # s = [ "cat", " ", "dog" ].inject("The result is:", :+) + # s #=> "The result is: cat dog" # - # This call to `inject` computes the sum of the operands: + # Here's a more complex example when the result object maintains state of a + # different type to the enumerable elements. # - # (1..4).inject(:+) # => 10 + # class Turtle # - # Examples with various methods: + # def initialize + # @x = @y = 0 + # end # - # # Integer addition. - # (1..4).inject(:+) # => 10 - # # Integer multiplication. - # (1..4).inject(:*) # => 24 - # # Character range concatenation. - # ('a'..'d').inject('', :+) # => "abcd" - # # String array concatenation. - # %w[foo bar baz].inject('', :+) # => "foobarbaz" - # # Hash update. - # h = [{foo: 0, bar: 1}, {baz: 2}, {bat: 3}].inject(:update) - # h # => {:foo=>0, :bar=>1, :baz=>2, :bat=>3} - # # Hash conversion to nested arrays. - # h = {foo: 0, bar: 1}.inject([], :push) - # h # => [[:foo, 0], [:bar, 1]] + # def move(dir) + # case dir + # when "n" then @y += 1 + # when "s" then @y -= 1 + # when "e" then @x += 1 + # when "w" then @x -= 1 + # end + # self + # end + # end # - # **Combination by Given Block** + # position = "nnneesw".chars.reduce(Turtle.new, :move) + # position #=>> # # - # If a block is given, the operands are passed to the block: + # **Third Shortcut: Reducer With no Initial Value** # - # * The first call passes the first and second operands. - # * The second call passes the result of the first call, along with the third - # operand. - # * The third call passes the result of the second call, along with the fourth - # operand. - # * And so on. + # If your reducer returns a value that it can accept as a parameter, then you + # don't have to pass in an initial value. Here `:*` is the name of the *times* + # function: # - # The return value from `inject` is the return value from the last block call. + # product = [ 2, 3, 4 ].inject(:*) + # product # => 24 # - # This call to `inject` gives a block that writes the memo and element, and also - # sums the elements: + # String concatenation again: # - # (1..4).inject do |memo, element| - # p "Memo: #{memo}; element: #{element}" - # memo + element - # end # => 10 + # s = [ "cat", " ", "dog" ].inject(:+) + # s #=> "cat dog" # - # Output: + # And an example that converts a hash to an array of two-element subarrays. # - # "Memo: 1; element: 2" - # "Memo: 3; element: 3" - # "Memo: 6; element: 4" + # nested = {foo: 0, bar: 1}.inject([], :push) + # nested # => [[:foo, 0], [:bar, 1]] # alias reduce inject @@ -1822,29 +1840,47 @@ module Enumerable[unchecked out Elem] : _Each[Elem] # - # Returns a hash containing the counts of equal elements: + # When argument `hash` is not given, returns a new hash whose keys are the + # distinct elements in `self`; each integer value is the count of occurrences of + # each element: + # + # %w[a b c b c a c b].tally # => {"a"=>2, "b"=>3, "c"=>3} # - # * Each key is an element of `self`. - # * Each value is the number elements equal to that key. + # When argument `hash` is given, returns `hash`, possibly augmented; for each + # element `ele` in `self`: # - # With no argument: + # * Adds it as a key with a zero value if that key does not already exist: # - # %w[a b c b c a c b].tally # => {"a"=>2, "b"=>3, "c"=>3} + # hash[ele] = 0 unless hash.include?(ele) + # + # * Increments the value of key `ele`: + # + # hash[ele] += 1 + # + # This is useful for accumulating tallies across multiple enumerables: + # + # h = {} # => {} + # %w[a c d b c a].tally(h) # => {"a"=>2, "c"=>2, "d"=>1, "b"=>1} + # %w[b a z].tally(h) # => {"a"=>3, "c"=>2, "d"=>1, "b"=>2, "z"=>1} + # %w[b a m].tally(h) # => {"a"=>4, "c"=>2, "d"=>1, "b"=>3, "z"=>1, "m"=>1} + # + # The key to be added or found for an element depends on the class of `self`; + # see [Enumerable in Ruby + # Classes](rdoc-ref:Enumerable@Enumerable+in+Ruby+Classes). + # + # Examples: + # + # * Array (and certain array-like classes): the key is the element (as above). + # * Hash (and certain hash-like classes): the key is the 2-element array + # formed from the key-value pair: # - # With a hash argument, that hash is used for the tally (instead of a new hash), - # and is returned; this may be useful for accumulating tallies across multiple - # enumerables: - # - # hash = {} - # hash = %w[a c d b c a].tally(hash) - # hash # => {"a"=>2, "c"=>2, "d"=>1, "b"=>1} - # hash = %w[b a z].tally(hash) - # hash # => {"a"=>3, "c"=>2, "d"=>1, "b"=>2, "z"=>1} - # hash = %w[b a m].tally(hash) - # hash # => {"a"=>4, "c"=>2, "d"=>1, "b"=>3, "z"=>1, "m"=> 1} + # h = {} # => {} + # {foo: 'a', bar: 'b'}.tally(h) # => {[:foo, "a"]=>1, [:bar, "b"]=>1} + # {foo: 'c', bar: 'd'}.tally(h) # => {[:foo, "a"]=>1, [:bar, "b"]=>1, [:foo, "c"]=>1, [:bar, "d"]=>1} + # {foo: 'a', bar: 'b'}.tally(h) # => {[:foo, "a"]=>2, [:bar, "b"]=>2, [:foo, "c"]=>1, [:bar, "d"]=>1} + # {foo: 'c', bar: 'd'}.tally(h) # => {[:foo, "a"]=>2, [:bar, "b"]=>2, [:foo, "c"]=>2, [:bar, "d"]=>2} # def tally: (?Hash[Elem, Integer] hash) -> ::Hash[Elem, Integer] diff --git a/core/env.rbs b/core/env.rbs index 438fdaed68..0bbb3cda9a 100644 --- a/core/env.rbs +++ b/core/env.rbs @@ -1,5 +1,5 @@ # -# ENV is a Hash-like accessor for environment variables. +# `ENV` is a Hash-like accessor for environment variables. # # See ENV (the class) for more details. # diff --git a/core/errno.rbs b/core/errno.rbs index 46df0ca706..00da4ca024 100644 --- a/core/errno.rbs +++ b/core/errno.rbs @@ -1,25 +1,42 @@ # -# Ruby exception objects are subclasses of Exception. However, operating -# systems typically report errors using plain integers. Module Errno is created -# dynamically to map these operating system errors to Ruby classes, with each -# error number generating its own subclass of SystemCallError. As the subclass -# is created in module Errno, its name will start `Errno::`. +# When an operating system encounters an error, it typically reports the error +# as an integer error code: # -# The names of the `Errno::` classes depend on the environment in which Ruby -# runs. On a typical Unix or Windows platform, there are Errno classes such as -# Errno::EACCES, Errno::EAGAIN, Errno::EINTR, and so on. +# $ ls nosuch.txt +# ls: cannot access 'nosuch.txt': No such file or directory +# $ echo $? # Code for last error. +# 2 # -# The integer operating system error number corresponding to a particular error -# is available as the class constant `Errno::`*error*`::Errno`. +# When the Ruby interpreter interacts with the operating system and receives +# such an error code (e.g., `2`), it maps the code to a particular Ruby +# exception class (e.g., `Errno::ENOENT`): # -# Errno::EACCES::Errno #=> 13 -# Errno::EAGAIN::Errno #=> 11 -# Errno::EINTR::Errno #=> 4 +# File.open('nosuch.txt') +# # => No such file or directory @ rb_sysopen - nosuch.txt (Errno::ENOENT) # -# The full list of operating system errors on your particular platform are -# available as the constants of Errno. +# Each such class is: # -# Errno.constants #=> :E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, ... +# * A nested class in this module, `Errno`. +# * A subclass of class SystemCallError. +# * Associated with an error code. +# +# Thus: +# +# Errno::ENOENT.superclass # => SystemCallError +# Errno::ENOENT::Errno # => 2 +# +# The names of nested classes are returned by method `Errno.constants`: +# +# Errno.constants.size # => 158 +# Errno.constants.sort.take(5) # => [:E2BIG, :EACCES, :EADDRINUSE, :EADDRNOTAVAIL, :EADV] +# +# As seen above, the error code associated with each class is available as the +# value of a constant; the value for a particular class may vary among operating +# systems. If the class is not needed for the particular operating system, the +# value is zero: +# +# Errno::ENOENT::Errno # => 2 +# Errno::ENOTCAPABLE::Errno # => 0 # module Errno class NOERROR < SystemCallError diff --git a/core/errors.rbs b/core/errors.rbs index e54084cefa..f6177d9f74 100644 --- a/core/errors.rbs +++ b/core/errors.rbs @@ -190,7 +190,7 @@ end # class LoadError < ScriptError # - # the path failed to load + # the path that failed to load # def path: () -> String? end @@ -564,7 +564,7 @@ class SyntaxError < ScriptError def initialize: (?string msg) -> void # - # the path failed to parse + # the path that failed to parse # def path: () -> String? end diff --git a/core/exception.rbs b/core/exception.rbs index 328fc7a52b..b75de59995 100644 --- a/core/exception.rbs +++ b/core/exception.rbs @@ -1,63 +1,25 @@ # -# Class Exception and its subclasses are used to communicate between -# Kernel#raise and `rescue` statements in `begin ... end` blocks. +# Class `Exception` and its subclasses are used to indicate that an error or +# other problem has occurred, and may need to be handled. See +# [Exceptions](rdoc-ref:exceptions.md). # -# An Exception object carries information about an exception: -# * Its type (the exception's class). -# * An optional descriptive message. -# * Optional backtrace information. +# An `Exception` object carries certain information: # -# Some built-in subclasses of Exception have additional methods: e.g., -# NameError#name. +# * The type (the exception's class), commonly StandardError, RuntimeError, or +# a subclass of one or the other; see [Built-In Exception Class +# Hierarchy](rdoc-ref:Exception@Built-In+Exception+Class+Hierarchy). +# * An optional descriptive message; see methods ::new, #message. +# * Optional backtrace information; see methods #backtrace, +# #backtrace_locations, #set_backtrace. +# * An optional cause; see method #cause. # -# ## Defaults +# ## Built-In Exception Class Hierarchy # -# Two Ruby statements have default exception classes: -# * `raise`: defaults to RuntimeError. -# * `rescue`: defaults to StandardError. -# -# ## Global Variables -# -# When an exception has been raised but not yet handled (in `rescue`, `ensure`, -# `at_exit` and `END` blocks), two global variables are set: -# * `$!` contains the current exception. -# * `$@` contains its backtrace. -# -# ## Custom Exceptions -# -# To provide additional or alternate information, a program may create custom -# exception classes that derive from the built-in exception classes. -# -# A good practice is for a library to create a single "generic" exception class -# (typically a subclass of StandardError or RuntimeError) and have its other -# exception classes derive from that class. This allows the user to rescue the -# generic exception, thus catching all exceptions the library may raise even if -# future versions of the library add new exception subclasses. -# -# For example: -# -# class MyLibrary -# class Error < ::StandardError -# end -# -# class WidgetError < Error -# end -# -# class FrobError < Error -# end -# -# end -# -# To handle both MyLibrary::WidgetError and MyLibrary::FrobError the library -# user can rescue MyLibrary::Error. -# -# ## Built-In Exception Classes -# -# The built-in subclasses of Exception are: +# The hierarchy of built-in subclasses of class `Exception`: # # * NoMemoryError # * ScriptError -# * LoadError +# * [LoadError](https://docs.ruby-lang.org/en/master/LoadError.html) # * NotImplementedError # * SyntaxError # * SecurityError @@ -83,212 +45,331 @@ # * RuntimeError # * FrozenError # * SystemCallError -# * Errno::* +# * Errno (and its subclasses, representing system errors) # * ThreadError # * TypeError # * ZeroDivisionError # * SystemExit # * SystemStackError -# * fatal +# * [fatal](https://docs.ruby-lang.org/en/master/fatal.html) # class Exception # - # Returns `true` if exception messages will be sent to a tty. + # Returns `true` if exception messages will be sent to a terminal device. # def self.to_tty?: () -> bool # - # With no argument, or if the argument is the same as the receiver, return the - # receiver. Otherwise, create a new exception object of the same class as the - # receiver, but with a message equal to `string.to_str`. + # Returns an exception object of the same class as `self`; useful for creating a + # similar exception, but with a different message. + # + # With `message` `nil`, returns `self`: + # + # x0 = StandardError.new('Boom') # => # + # x1 = x0.exception # => # + # x0.__id__ == x1.__id__ # => true + # + # With [string-convertible + # object](rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects) + # `message` (even the same as the original message), returns a new exception + # object whose class is the same as `self`, and whose message is the given + # `message`: + # + # x1 = x0.exception('Boom') # => # + # x0..equal?(x1) # => false # def self.exception: (?string | _ToS msg) -> instance # - # Equality---If *obj* is not an Exception, returns `false`. Otherwise, returns - # `true` if *exc* and *obj* share same class, messages, and backtrace. + # Returns whether `object` is the same class as `self` and its #message and + # #backtrace are equal to those of `self`. # def ==: (untyped obj) -> bool # - # Returns any backtrace associated with the exception. The backtrace is an array - # of strings, each containing either ``filename:lineNo: in `method''' or - # ``filename:lineNo.'' + # Returns a backtrace value for `self`; the returned value depends on the form + # of the stored backtrace value: # - # def a - # raise "boom" - # end + # * Array of Thread::Backtrace::Location objects: returns the array of strings + # given by `Exception#backtrace_locations.map {|loc| loc.to_s }`. This is + # the normal case, where the backtrace value was stored by Kernel#raise. + # * Array of strings: returns that array. This is the unusual case, where the + # backtrace value was explicitly stored as an array of strings. + # * `nil`: returns `nil`. # - # def b - # a() - # end + # Example: # # begin - # b() - # rescue => detail - # print detail.backtrace.join("\n") + # 1 / 0 + # rescue => x + # x.backtrace.take(2) # end + # # => ["(irb):132:in `/'", "(irb):132:in `'"] # - # *produces:* - # - # prog.rb:2:in `a' - # prog.rb:6:in `b' - # prog.rb:10 - # - # In the case no backtrace has been set, `nil` is returned - # - # ex = StandardError.new - # ex.backtrace - # #=> nil + # see [Backtraces](rdoc-ref:exceptions.md@Backtraces). # def backtrace: () -> Array[String]? # - # Returns any backtrace associated with the exception. This method is similar to - # Exception#backtrace, but the backtrace is an array of - # Thread::Backtrace::Location. + # Returns a backtrace value for `self`; the returned value depends on the form + # of the stored backtrace value: + # + # * Array of Thread::Backtrace::Location objects: returns that array. + # * Array of strings or `nil`: returns `nil`. + # + # Example: # - # This method is not affected by Exception#set_backtrace(). + # begin + # 1 / 0 + # rescue => x + # x.backtrace_locations.take(2) + # end + # # => ["(irb):150:in `/'", "(irb):150:in `'"] + # + # See [Backtraces](rdoc-ref:exceptions.md@Backtraces). # def backtrace_locations: () -> Array[Thread::Backtrace::Location]? # - # Returns the previous exception ($!) at the time this exception was raised. - # This is useful for wrapping exceptions and retaining the original exception - # information. + # Returns the previous value of global variable `$!`, which may be `nil` (see + # [Global Variables](rdoc-ref:exceptions.md@Global+Variables)): + # + # begin + # raise('Boom 0') + # rescue => x0 + # puts "Exception: #{x0}; $!: #{$!}; cause: #{x0.cause.inspect}." + # begin + # raise('Boom 1') + # rescue => x1 + # puts "Exception: #{x1}; $!: #{$!}; cause: #{x1.cause}." + # begin + # raise('Boom 2') + # rescue => x2 + # puts "Exception: #{x2}; $!: #{$!}; cause: #{x2.cause}." + # end + # end + # end + # + # Output: + # + # Exception: Boom 0; $!: Boom 0; cause: nil. + # Exception: Boom 1; $!: Boom 1; cause: Boom 0. + # Exception: Boom 2; $!: Boom 2; cause: Boom 1. # def cause: () -> Exception? # - # Processes a string returned by #message. - # - # It may add the class name of the exception to the end of the first line. Also, - # when `highlight` keyword is true, it adds ANSI escape sequences to make the - # message bold. - # - # If you override this method, it must be tolerant for unknown keyword - # arguments. All keyword arguments passed to #full_message are delegated to this - # method. - # - # This method is overridden by did_you_mean and error_highlight to add their - # information. - # - # A user-defined exception class can also define their own `detailed_message` - # method to add supplemental information. When `highlight` is true, it can - # return a string containing escape sequences, but use widely-supported ones. It - # is recommended to limit the following codes: - # - # * Reset (`\e[0m`) - # * Bold (`\e[1m`) - # * Underline (`\e[4m`) - # * Foreground color except white and black - # * Red (`\e[31m`) - # * Green (`\e[32m`) - # * Yellow (`\e[33m`) - # * Blue (`\e[34m`) - # * Magenta (`\e[35m`) - # * Cyan (`\e[36m`) - # - # Use escape sequences carefully even if `highlight` is true. Do not use escape - # sequences to express essential information; the message should be readable - # even if all escape sequences are ignored. + # Returns the message string with enhancements: + # + # * Includes the exception class name in the first line. + # * If the value of keyword `highlight` is `true`, includes bolding and + # underlining ANSI codes (see below) to enhance the appearance of the + # message. + # + # Examples: + # + # begin + # 1 / 0 + # rescue => x + # p x.message + # p x.detailed_message # Class name added. + # p x.detailed_message(highlight: true) # Class name, bolding, and underlining added. + # end + # + # Output: + # + # "divided by 0" + # "divided by 0 (ZeroDivisionError)" + # "\e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m" + # + # This method is overridden by some gems in the Ruby standard library to add + # information: + # + # * DidYouMean::Correctable#detailed_message. + # * ErrorHighlight::CoreExt#detailed_message. + # * SyntaxSuggest#detailed_message. + # + # An overriding method must be tolerant of passed keyword arguments, which may + # include (but may not be limited to): + # + # * `:highlight`. + # * `:did_you_mean`. + # * `:error_highlight`. + # * `:syntax_suggest`. + # + # An overriding method should also be careful with ANSI code enhancements; see + # [Messages](rdoc-ref:exceptions.md@Messages). # def detailed_message: (?highlight: bool?, **untyped ignored) -> String # - # With no argument, or if the argument is the same as the receiver, return the - # receiver. Otherwise, create a new exception object of the same class as the - # receiver, but with a message equal to `string.to_str`. + # Returns an exception object of the same class as `self`; useful for creating a + # similar exception, but with a different message. + # + # With `message` `nil`, returns `self`: + # + # x0 = StandardError.new('Boom') # => # + # x1 = x0.exception # => # + # x0.__id__ == x1.__id__ # => true + # + # With [string-convertible + # object](rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects) + # `message` (even the same as the original message), returns a new exception + # object whose class is the same as `self`, and whose message is the given + # `message`: + # + # x1 = x0.exception('Boom') # => # + # x0..equal?(x1) # => false # def exception: (?self) -> self | (string | _ToS message) -> instance # - # Construct a new Exception object, optionally passing in a message. + # Returns a new exception object. + # + # The given `message` should be a [string-convertible + # object](rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects); see + # method #message; if not given, the message is the class name of the new + # instance (which may be the name of a subclass): + # + # Examples: + # + # Exception.new # => # + # LoadError.new # => # # Subclass of Exception. + # Exception.new('Boom') # => # # def initialize: (?string | _ToS message) -> void # - # Return this exception's class name and message. + # Returns a string representation of `self`: + # + # x = RuntimeError.new('Boom') + # x.inspect # => "#" + # x = RuntimeError.new + # x.inspect # => "#" # def inspect: () -> String # - # Returns the result of invoking `exception.to_s`. Normally this returns the - # exception's message or name. + # Returns #to_s. + # + # See [Messages](rdoc-ref:exceptions.md@Messages). # def message: () -> String # - # Sets the backtrace information associated with `exc`. The `backtrace` must be - # an array of String objects or a single String in the format described in - # Exception#backtrace. + # Sets the backtrace value for `self`; returns the given +value: + # + # x = RuntimeError.new('Boom') + # x.set_backtrace(%w[foo bar baz]) # => ["foo", "bar", "baz"] + # x.backtrace # => ["foo", "bar", "baz"] + # + # The given `value` must be an array of strings, a single string, or `nil`. + # + # Does not affect the value returned by #backtrace_locations. + # + # See [Backtraces](rdoc-ref:exceptions.md@Backtraces). # def set_backtrace: (String | Array[String] backtrace) -> Array[String] | (nil) -> nil # - # Returns exception's message (or the name of the exception if no message is - # set). + # Returns a string representation of `self`: + # + # x = RuntimeError.new('Boom') + # x.to_s # => "Boom" + # x = RuntimeError.new + # x.to_s # => "RuntimeError" # def to_s: () -> String # - # Returns formatted string of *exception*. The returned string is formatted - # using the same format that Ruby uses when printing an uncaught exceptions to - # stderr. + # Returns an enhanced message string: + # + # * Includes the exception class name. + # * If the value of keyword `highlight` is true (not `nil` or `false`), + # includes bolding ANSI codes (see below) to enhance the appearance of the + # message. + # * Includes the [backtrace](rdoc-ref:exceptions.md@Backtraces): + # + # * If the value of keyword `order` is `:top` (the default), lists the + # error message and the innermost backtrace entry first. + # * If the value of keyword `order` is `:bottom`, lists the error message + # the the innermost entry last. + # + # Example: + # + # def baz + # begin + # 1 / 0 + # rescue => x + # pp x.message + # pp x.full_message(highlight: false).split("\n") + # pp x.full_message.split("\n") + # end + # end + # def bar; baz; end + # def foo; bar; end + # foo # - # If *highlight* is `true` the default error handler will send the messages to a - # tty. + # Output: # - # *order* must be either of `:top` or `:bottom`, and places the error message - # and the innermost backtrace come at the top or the bottom. + # "divided by 0" + # ["t.rb:3:in `/': divided by 0 (ZeroDivisionError)", + # "\tfrom t.rb:3:in `baz'", + # "\tfrom t.rb:10:in `bar'", + # "\tfrom t.rb:11:in `foo'", + # "\tfrom t.rb:12:in `
'"] + # ["t.rb:3:in `/': \e[1mdivided by 0 (\e[1;4mZeroDivisionError\e[m\e[1m)\e[m", + # "\tfrom t.rb:3:in `baz'", + # "\tfrom t.rb:10:in `bar'", + # "\tfrom t.rb:11:in `foo'", + # "\tfrom t.rb:12:in `
'"] # - # The default values of these options depend on `$stderr` and its `tty?` at the - # timing of a call. + # An overriding method should be careful with ANSI code enhancements; see + # [Messages](rdoc-ref:exceptions.md@Messages). # def full_message: (?highlight: bool?, ?order: (:top | :bottom | string)?) -> String end diff --git a/core/fiber.rbs b/core/fiber.rbs index 6cd124aa60..d6542f4a2f 100644 --- a/core/fiber.rbs +++ b/core/fiber.rbs @@ -412,6 +412,8 @@ class Fiber < Object # # Raises `FiberError` if called on a Fiber belonging to another `Thread`. # + # See Kernel#raise for more information. + # def raise: (?string msg) -> untyped | (_Exception, ?string msg, ?Array[string] backtrace) -> untyped diff --git a/core/file.rbs b/core/file.rbs index 1c4a8542df..c341878b70 100644 --- a/core/file.rbs +++ b/core/file.rbs @@ -1816,46 +1816,19 @@ class File < IO # rdoc-file=file.c # - flock(locking_constant) -> 0 or false # --> - # Locks or unlocks a file according to the given `locking_constant`, + # Locks or unlocks file `self` 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.
+ # Constant | Lock | Effect + # ---------------|------------|-------------------------------------------------------------------------------------------------------------- + # +File::LOCK_EX+| Exclusive | Only one process may hold an exclusive lock for +self+ at a time. + # +File::LOCK_NB+|Non-blocking|No blocking; may be combined with +File::LOCK_SH+ or +File::LOCK_EX+ using the bitwise OR operator |. + # +File::LOCK_SH+| Shared | Multiple processes may each hold a shared lock for +self+ at the same time. + # +File::LOCK_UN+| Unlock | Remove an existing lock held by this process. + # Example: # # 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| @@ -2023,7 +1996,7 @@ File::Separator: String # # #### File::RDONLY # -# Flag File::RDONLY specifies the the stream should be opened for reading only: +# Flag File::RDONLY specifies the stream should be opened for reading only: # # filepath = '/tmp/t.tmp' # f = File.new(filepath, File::RDONLY) @@ -2190,11 +2163,13 @@ File::Separator: String # # Flag File::BINARY specifies that the stream is to be accessed in binary mode. # -# #### File::SHARE_DELETE (Windows Only) +# #### File::SHARE_DELETE # # Flag File::SHARE_DELETE enables other processes to open the stream with delete # access. # +# Windows only. +# # If the stream is opened for (local) delete access without File::SHARE_DELETE, # and another process attempts to open it with delete access, the attempt fails # and the stream is not opened for that process. @@ -2265,9 +2240,11 @@ File::Separator: String # Flag File::FNM_PATHNAME specifies that patterns `'*'` and `'?'` do not match # the directory separator (the value of constant File::SEPARATOR). # -# #### File::FNM_SHORTNAME (Windows Only) +# #### File::FNM_SHORTNAME +# +# Flag File::FNM_SHORTNAME allows patterns to match short names if they exist. # -# Flag File::FNM_SHORTNAME Allows patterns to match short names if they exist. +# Windows only. # # #### File::FNM_SYSCASE # @@ -2421,8 +2398,7 @@ File::Constants::RDWR: Integer File::Constants::RSYNC: Integer # -# [File::SHARE_DELETE](rdoc-ref:File::Constants@File-3A-3ASHARE_DELETE+-28Window -# s+Only-29) +# [File::SHARE_DELETE](rdoc-ref:File::Constants@File-3A-3ASHARE_DELETE) # File::Constants::SHARE_DELETE: Integer diff --git a/core/float.rbs b/core/float.rbs index d4fce75297..64f896c380 100644 --- a/core/float.rbs +++ b/core/float.rbs @@ -22,7 +22,9 @@ # # First, what's elsewhere. Class Float: # -# * Inherits from [class Numeric](rdoc-ref:Numeric@What-27s+Here). +# * Inherits from [class Numeric](rdoc-ref:Numeric@What-27s+Here) and [class +# Object](rdoc-ref:Object@What-27s+Here). +# * Includes [module Comparable](rdoc-ref:Comparable@What-27s+Here). # # Here, class Float provides methods for: # @@ -343,33 +345,58 @@ class Float < Numeric # rdoc-file=numeric.c # - ceil(ndigits = 0) -> float or integer # --> - # Returns the smallest number greater than or equal to `self` with a precision - # of `ndigits` decimal digits. - # - # When `ndigits` is positive, returns a float with `ndigits` digits after the - # decimal point (as available): - # - # f = 12345.6789 - # f.ceil(1) # => 12345.7 - # f.ceil(3) # => 12345.679 - # f = -12345.6789 - # f.ceil(1) # => -12345.6 - # f.ceil(3) # => -12345.678 - # - # When `ndigits` is non-positive, returns an integer with at least `ndigits.abs` - # trailing zeros: - # + # Returns a numeric that is a "ceiling" value for `self`, + # as specified by the given `ndigits`, + # which must be an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). + # When `ndigits` is positive, returns a Float with `ndigits` + # decimal digits after the decimal point + # (as available, but no fewer than 1): # f = 12345.6789 - # f.ceil(0) # => 12346 - # f.ceil(-3) # => 13000 - # f = -12345.6789 - # f.ceil(0) # => -12345 - # f.ceil(-3) # => -12000 - # - # Note that the limited precision of floating-point arithmetic may lead to - # surprising results: - # - # (2.1 / 0.7).ceil #=> 4 (!) + # f.ceil(1) # => 12345.7 + # f.ceil(3) # => 12345.679 + # f.ceil(30) # => 12345.6789 + # f = -12345.6789 + # f.ceil(1) # => -12345.6 + # f.ceil(3) # => -12345.678 + # f.ceil(30) # => -12345.6789 + # f = 0.0 + # f.ceil(1) # => 0.0 + # f.ceil(100) # => 0.0 + # + # When `ndigits` is non-positive, + # returns an Integer based on a computed granularity: + # * The granularity is `10 ** ndigits.abs`. + # * The returned value is the largest multiple of the granularity + # that is less than or equal to `self`. + # Examples with positive `self`: + # ndigits|Granularity|12345.6789.ceil(ndigits) + # -------|-----------|------------------------ + # 0| 1| 12346 + # -1| 10| 12350 + # -2| 100| 12400 + # -3| 1000| 13000 + # -4| 10000| 20000 + # -5| 100000| 100000 + # Examples with negative `self`: + # ndigits|Granularity|-12345.6789.ceil(ndigits) + # -------|-----------|------------------------- + # 0| 1| -12345 + # -1| 10| -12340 + # -2| 100| -12300 + # -3| 1000| -12000 + # -4| 10000| -10000 + # -5| 100000| 0 + # When `self` is zero and `ndigits` is non-positive, + # returns Integer zero: + # 0.0.ceil(0) # => 0 + # 0.0.ceil(-1) # => 0 + # 0.0.ceil(-2) # => 0 + # + # Note that the limited precision of floating-point arithmetic + # may lead to surprising results: + # (2.1 / 0.7).ceil #=> 4 # Not 3 (because 2.1 / 0.7 # => 3.0000000000000004, not 3.0) # # Related: Float#floor. # @@ -490,33 +517,59 @@ class Float < Numeric # rdoc-file=numeric.c # - floor(ndigits = 0) -> float or integer # --> - # Returns the largest number less than or equal to `self` with a precision of - # `ndigits` decimal digits. - # - # When `ndigits` is positive, returns a float with `ndigits` digits after the - # decimal point (as available): - # - # f = 12345.6789 - # f.floor(1) # => 12345.6 - # f.floor(3) # => 12345.678 - # f = -12345.6789 - # f.floor(1) # => -12345.7 - # f.floor(3) # => -12345.679 - # - # When `ndigits` is non-positive, returns an integer with at least `ndigits.abs` - # trailing zeros: - # + # Returns a float or integer that is a "floor" value for `self`, + # as specified by `ndigits`, + # which must be an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). + # When `self` is zero, + # returns a zero value: + # a float if `ndigits` is positive, + # an integer otherwise: + # f = 0.0 # => 0.0 + # f.floor(20) # => 0.0 + # f.floor(0) # => 0 + # f.floor(-20) # => 0 + # + # When `self` is non-zero and `ndigits` is positive, returns a float with + # `ndigits` + # digits after the decimal point (as available): # f = 12345.6789 - # f.floor(0) # => 12345 - # f.floor(-3) # => 12000 - # f = -12345.6789 - # f.floor(0) # => -12346 - # f.floor(-3) # => -13000 - # - # Note that the limited precision of floating-point arithmetic may lead to - # surprising results: - # - # (0.3 / 0.1).floor #=> 2 (!) + # f.floor(1) # => 12345.6 + # f.floor(3) # => 12345.678 + # f.floor(30) # => 12345.6789 + # f = -12345.6789 + # f.floor(1) # => -12345.7 + # f.floor(3) # => -12345.679 + # f.floor(30) # => -12345.6789 + # + # When `self` is non-zero and `ndigits` is non-positive, + # returns an integer value based on a computed granularity: + # * The granularity is `10 ** ndigits.abs`. + # * The returned value is the largest multiple of the granularity + # that is less than or equal to `self`. + # Examples with positive `self`: + # ndigits|Granularity|12345.6789.floor(ndigits) + # -------|-----------|------------------------- + # 0| 1| 12345 + # -1| 10| 12340 + # -2| 100| 12300 + # -3| 1000| 12000 + # -4| 10000| 10000 + # -5| 100000| 0 + # Examples with negative `self`: + # ndigits|Granularity|-12345.6789.floor(ndigits) + # -------|-----------|-------------------------- + # 0| 1| -12346 + # -1| 10| -12350 + # -2| 100| -12400 + # -3| 1000| -13000 + # -4| 10000| -20000 + # -5| 100000| -100000 + # -6| 1000000| -1000000 + # Note that the limited precision of floating-point arithmetic + # may lead to surprising results: + # (0.3 / 0.1).floor # => 2 # Not 3, (because (0.3 / 0.1) # => 2.9999999999999996, not 3.0) # # Related: Float#ceil. # @@ -567,14 +620,19 @@ class Float < Numeric # of `self`, the string representation may contain: # # * A fixed-point number. + # 3.14.to_s # => "3.14" + # # * A number in "scientific notation" (containing an exponent). + # (10.1**50).to_s # => "1.644631821843879e+50" + # # * 'Infinity'. + # (10.1**500).to_s # => "Infinity" + # # * '-Infinity'. - # * 'NaN' (indicating not-a-number). + # (-10.1**500).to_s # => "-Infinity" # - # 3.14.to_s # => "3.14" (10.1**50).to_s # => - # "1.644631821843879e+50" (10.1**500).to_s # => "Infinity" - # (-10.1**500).to_s # => "-Infinity" (0.0/0.0).to_s # => "NaN" + # * 'NaN' (indicating not-a-number). + # (0.0/0.0).to_s # => "NaN" # alias inspect to_s @@ -789,7 +847,7 @@ class Float < Numeric # # Returns `self` rounded to the nearest value with a precision of `ndigits` # decimal digits. @@ -916,14 +974,19 @@ class Float < Numeric # of `self`, the string representation may contain: # # * A fixed-point number. + # 3.14.to_s # => "3.14" + # # * A number in "scientific notation" (containing an exponent). + # (10.1**50).to_s # => "1.644631821843879e+50" + # # * 'Infinity'. + # (10.1**500).to_s # => "Infinity" + # # * '-Infinity'. - # * 'NaN' (indicating not-a-number). + # (-10.1**500).to_s # => "-Infinity" # - # 3.14.to_s # => "3.14" (10.1**50).to_s # => - # "1.644631821843879e+50" (10.1**500).to_s # => "Infinity" - # (-10.1**500).to_s # => "-Infinity" (0.0/0.0).to_s # => "NaN" + # * 'NaN' (indicating not-a-number). + # (0.0/0.0).to_s # => "NaN" # def to_s: () -> String diff --git a/core/gc.rbs b/core/gc.rbs index c05db579d4..efe3fc0262 100644 --- a/core/gc.rbs +++ b/core/gc.rbs @@ -1,5 +1,5 @@ # -# The GC module provides an interface to Ruby's mark and sweep garbage +# The GC module provides an interface to Ruby's mark-and-sweep garbage # collection mechanism. # # Some of the underlying methods are also available via the ObjectSpace module. @@ -161,15 +161,13 @@ module GC # rdoc-file=gc.rb # - GC.count -> Integer # --> - # The number of times GC occurred. - # - # It returns the number of times GC occurred since the process started. + # Returns the number of times GC has occurred since the process started. # def self.count: () -> Integer # # Disables garbage collection, returning `true` if garbage collection was # already disabled. @@ -181,7 +179,7 @@ module GC # # Enables garbage collection, returning `true` if garbage collection was # previously disabled. @@ -200,24 +198,24 @@ module GC # # The `full_mark` keyword argument determines whether or not to perform a major # garbage collection cycle. When set to `true`, a major garbage collection cycle - # is ran, meaning all objects are marked. When set to `false`, a minor garbage - # collection cycle is ran, meaning only young objects are marked. + # is run, meaning all objects are marked. When set to `false`, a minor garbage + # collection cycle is run, meaning only young objects are marked. # # The `immediate_mark` keyword argument determines whether or not to perform # incremental marking. When set to `true`, marking is completed during the call - # to this method. When set to `false`, marking is performed in steps that is + # to this method. When set to `false`, marking is performed in steps that are # interleaved with future Ruby code execution, so marking might not be completed - # during this method call. Note that if `full_mark` is `false` then marking will - # always be immediate, regardless of the value of `immediate_mark`. + # during this method call. Note that if `full_mark` is `false`, then marking + # will always be immediate, regardless of the value of `immediate_mark`. # - # The `immedate_sweep` keyword argument determines whether or not to defer - # sweeping (using lazy sweep). When set to `true`, sweeping is performed in - # steps that is interleaved with future Ruby code execution, so sweeping might - # not be completed during this method call. When set to `false`, sweeping is + # The `immediate_sweep` keyword argument determines whether or not to defer + # sweeping (using lazy sweep). When set to `false`, sweeping is performed in + # steps that are interleaved with future Ruby code execution, so sweeping might + # not be completed during this method call. When set to `true`, sweeping is # completed during the call to this method. # - # Note: These keyword arguments are implementation and version dependent. They - # are not guaranteed to be future-compatible, and may be ignored if the + # Note: These keyword arguments are implementation and version-dependent. They + # are not guaranteed to be future-compatible and may be ignored if the # underlying implementation does not support them. # def self.start: (?immediate_sweep: boolish, ?immediate_mark: boolish, ?full_mark: boolish) -> nil @@ -230,13 +228,13 @@ module GC # --> # Returns a Hash containing information about the GC. # - # The contents of the hash are implementation specific and may change in the + # The contents of the hash are implementation-specific and may change in the # future without notice. # - # The hash includes information about internal statistics about GC such as: + # The hash includes internal statistics about GC such as: # # count - # : The total number of garbage collections ran since application start (count + # : The total number of garbage collections run since application start (count # includes both minor and major garbage collections) # # time @@ -325,12 +323,11 @@ module GC # : Amount of memory allocated on the heap for objects. Decreased by major GC # # oldmalloc_increase_bytes_limit - # : When `:old_malloc_increase_bytes` crosses this limit, major GC is - # triggered + # : When `:oldmalloc_increase_bytes` crosses this limit, major GC is triggered # # # If the optional argument, hash, is given, it is overwritten and returned. This - # is intended to avoid probe effect. + # is intended to avoid the probe effect. # # This method is only expected to work on CRuby. # @@ -341,7 +338,7 @@ module GC # rdoc-file=gc.rb # - GC.measure_total_time = true/false # --> - # Enable to measure GC time. You can get the result with `GC.stat(:time)`. Note + # Enables measuring GC time. You can get the result with `GC.stat(:time)`. Note # that GC time measurement can cause some performance overhead. # def self.measure_total_time=: [T] (T enable) -> T @@ -350,8 +347,8 @@ module GC # rdoc-file=gc.rb # - GC.measure_total_time -> true/false # --> - # Return measure_total_time flag (default: `true`). Note that measurement can - # affect the application performance. + # Returns the measure_total_time flag (default: `true`). Note that measurement + # can affect the application's performance. # def self.measure_total_time: () -> bool @@ -390,16 +387,16 @@ module GC # it will return a `Hash` with heap names as keys and a `Hash` containing # information about the heap as values. # - # If the second optional argument, `hash_or_key`, is given as `Hash`, it will be - # overwritten and returned. This is intended to avoid the probe effect. + # If the second optional argument, `hash_or_key`, is given as a `Hash`, it will + # be overwritten and returned. This is intended to avoid the probe effect. # # If both optional arguments are passed in and the second optional argument is a - # symbol, it will return a `Numeric` of the value for the particular heap. + # symbol, it will return a `Numeric` value for the particular heap. # # On CRuby, `heap_name` is of the type `Integer` but may be of type `String` on # other implementations. # - # The contents of the hash are implementation specific and may change in the + # The contents of the hash are implementation-specific and may change in the # future without notice. # # If the optional argument, hash, is given, it is overwritten and returned. @@ -436,7 +433,7 @@ module GC # system in the heap. # # force_major_gc_count - # : The number of times major garbage collection cycles this heap has forced + # : The number of times this heap has forced major garbage collection cycles # to start due to running out of free slots. # # force_incremental_marking_finish_count @@ -462,24 +459,25 @@ module GC # - # Returns current status of GC stress mode. + # Returns the current status of GC stress mode. # def self.stress: () -> (Integer | bool) # # Updates the GC stress mode. # # When stress mode is enabled, the GC is invoked at every GC opportunity: all # memory and object allocations. # - # Enabling stress mode will degrade performance, it is only for debugging. + # Enabling stress mode will degrade performance; it is only for debugging. # - # flag can be true, false, or an integer bit-ORed following flags. + # The flag can be true, false, or an integer bitwise-ORed with the following + # flags: # 0x01:: no major GC # 0x02:: no immediate sweep # 0x04:: full mark after malloc/calloc/realloc @@ -491,7 +489,7 @@ module GC # rdoc-file=gc.rb # - GC.total_time -> int # --> - # Return measured GC total time in nano seconds. + # Returns the measured GC total time in nanoseconds. # def self.total_time: () -> Integer @@ -550,12 +548,15 @@ module GC # rdoc-file=gc.rb # - GC.latest_gc_info -> hash # - GC.latest_gc_info(hash) -> hash - # - GC.latest_gc_info(:major_by) -> :malloc + # - GC.latest_gc_info(key) -> value # --> # Returns information about the most recent garbage collection. # - # If the optional argument, hash, is given, it is overwritten and returned. This - # is intended to avoid probe effect. + # If the argument `hash` is given and is a Hash object, it is overwritten and + # returned. This is intended to avoid the probe effect. + # + # If the argument `key` is given and is a Symbol object, it returns the value + # associated with the key. This is equivalent to `GC.latest_gc_info[key]`. # def self.latest_gc_info: (?Hash[Symbol, untyped]? hash) -> Hash[Symbol, untyped] | (Symbol key) -> untyped diff --git a/core/hash.rbs b/core/hash.rbs index 730ffcf6a5..3e6fa57918 100644 --- a/core/hash.rbs +++ b/core/hash.rbs @@ -1,18 +1,18 @@ # -# A Hash maps each of its unique keys to a specific value. +# A `Hash` maps each of its unique keys to a specific value. # -# A Hash has certain similarities to an Array, but: +# A `Hash` has certain similarities to an Array, but: # * An Array index is always an Integer. -# * A Hash key can be (almost) any object. +# * A `Hash` key can be (almost) any object. # -# ### Hash Data Syntax +# ### `Hash` Data Syntax # -# The older syntax for Hash data uses the "hash rocket," `=>`: +# The older syntax for `Hash` data uses the "hash rocket," `=>`: # # h = {:foo => 0, :bar => 1, :baz => 2} # h # => {:foo=>0, :bar=>1, :baz=>2} # -# Alternatively, but only for a Hash key that's a Symbol, you can use a newer +# Alternatively, but only for a `Hash` key that's a Symbol, you can use a newer # JSON-style syntax, where each bareword becomes a Symbol: # # h = {foo: 0, bar: 1, baz: 2} @@ -34,8 +34,8 @@ # # Raises SyntaxError (syntax error, unexpected ':', expecting =>): # h = {0: 'zero'} # -# Hash value can be omitted, meaning that value will be fetched from the context -# by the name of the key: +# `Hash` value can be omitted, meaning that value will be fetched from the +# context by the name of the key: # # x = 0 # y = 100 @@ -44,24 +44,24 @@ # # ### Common Uses # -# You can use a Hash to give names to objects: +# You can use a `Hash` to give names to objects: # # person = {name: 'Matz', language: 'Ruby'} # person # => {:name=>"Matz", :language=>"Ruby"} # -# You can use a Hash to give names to method arguments: +# You can use a `Hash` to give names to method arguments: # # def some_method(hash) # p hash # end # some_method({foo: 0, bar: 1, baz: 2}) # => {:foo=>0, :bar=>1, :baz=>2} # -# Note: when the last argument in a method call is a Hash, the curly braces may -# be omitted: +# Note: when the last argument in a method call is a `Hash`, the curly braces +# may be omitted: # # some_method(foo: 0, bar: 1, baz: 2) # => {:foo=>0, :bar=>1, :baz=>2} # -# You can use a Hash to initialize an object: +# You can use a `Hash` to initialize an object: # # class Dev # attr_accessor :name, :language @@ -73,9 +73,9 @@ # matz = Dev.new(name: 'Matz', language: 'Ruby') # matz # => # # -# ### Creating a Hash +# ### Creating a `Hash` # -# You can create a Hash object explicitly with: +# You can create a `Hash` object explicitly with: # # * A [hash literal](rdoc-ref:syntax/literals.rdoc@Hash+Literals). # @@ -83,46 +83,46 @@ # # * Method #Hash. # -# You can create a Hash by calling method Hash.new. +# You can create a `Hash` by calling method Hash.new. # -# Create an empty Hash: +# Create an empty `Hash`: # # h = Hash.new # h # => {} # h.class # => Hash # -# You can create a Hash by calling method Hash.[]. +# You can create a `Hash` by calling method Hash.[]. # -# Create an empty Hash: +# Create an empty `Hash`: # # h = Hash[] # h # => {} # -# Create a Hash with initial entries: +# Create a `Hash` with initial entries: # # h = Hash[foo: 0, bar: 1, baz: 2] # h # => {:foo=>0, :bar=>1, :baz=>2} # -# You can create a Hash by using its literal form (curly braces). +# You can create a `Hash` by using its literal form (curly braces). # -# Create an empty Hash: +# Create an empty `Hash`: # # h = {} # h # => {} # -# Create a Hash with initial entries: +# Create a `Hash` with initial entries: # # h = {foo: 0, bar: 1, baz: 2} # h # => {:foo=>0, :bar=>1, :baz=>2} # -# ### Hash Value Basics +# ### `Hash` Value Basics # -# The simplest way to retrieve a Hash value (instance method #[]): +# The simplest way to retrieve a `Hash` value (instance method #[]): # # h = {foo: 0, bar: 1, baz: 2} # h[:foo] # => 0 # -# The simplest way to create or update a Hash value (instance method #[]=): +# The simplest way to create or update a `Hash` value (instance method #[]=): # # h = {foo: 0, bar: 1, baz: 2} # h[:bat] = 3 # => 3 @@ -130,7 +130,7 @@ # h[:foo] = 4 # => 4 # h # => {:foo=>4, :bar=>1, :baz=>2, :bat=>3} # -# The simplest way to delete a Hash entry (instance method #delete): +# The simplest way to delete a `Hash` entry (instance method #delete): # # h = {foo: 0, bar: 1, baz: 2} # h.delete(:bar) # => 1 @@ -138,14 +138,14 @@ # # ### Entry Order # -# A Hash object presents its entries in the order of their creation. This is +# A `Hash` object presents its entries in the order of their creation. This is # seen in: # # * Iterative methods such as `each`, `each_key`, `each_pair`, `each_value`. # * Other order-sensitive methods such as `shift`, `keys`, `values`. # * The String returned by method `inspect`. # -# A new Hash has its initial ordering per the given entries: +# A new `Hash` has its initial ordering per the given entries: # # h = Hash[foo: 0, bar: 1] # h # => {:foo=>0, :bar=>1} @@ -166,18 +166,18 @@ # h[:foo] = 5 # h # => {:bar=>1, :baz=>3, :foo=>5} # -# ### Hash Keys +# ### `Hash` Keys # -# #### Hash Key Equivalence +# #### `Hash` Key Equivalence # # Two objects are treated as the same hash key when their `hash` value is # identical and the two objects are `eql?` to each other. # -# #### Modifying an Active Hash Key +# #### Modifying an Active `Hash` Key # -# Modifying a Hash key while it is in use damages the hash's index. +# Modifying a `Hash` key while it is in use damages the hash's index. # -# This Hash has keys that are Arrays: +# This `Hash` has keys that are Arrays: # # a0 = [ :foo, :bar ] # a1 = [ :baz, :bat ] @@ -191,7 +191,7 @@ # a0[0] = :bam # a0.hash # => 1069447059 # -# And damages the Hash index: +# And damages the `Hash` index: # # h.include?(a0) # => false # h[a0] # => nil @@ -211,10 +211,10 @@ # first_key = h.keys.first # first_key.frozen? # => true # -# #### User-Defined Hash Keys +# #### User-Defined `Hash` Keys # -# To be useable as a Hash key, objects must implement the methods `hash` and -# `eql?`. Note: this requirement does not apply if the Hash uses +# To be usable as a `Hash` key, objects must implement the methods `hash` and +# `eql?`. Note: this requirement does not apply if the `Hash` uses # #compare_by_identity since comparison will then rely on the keys' object id # instead of `hash` and `eql?`. # @@ -303,7 +303,7 @@ # # #### Default Proc # -# When the default proc for a Hash is set (i.e., not `nil`), the default value +# When the default proc for a `Hash` is set (i.e., not `nil`), the default value # returned by method #[] is determined by the default proc alone. # # You can retrieve the default proc with method #default_proc: @@ -320,8 +320,8 @@ # h.default_proc.class # => Proc # # When the default proc is set (i.e., not `nil`) and method #[] is called with -# with a non-existent key, #[] calls the default proc with both the Hash object -# itself and the missing key, then returns the proc's return value: +# with a non-existent key, #[] calls the default proc with both the `Hash` +# object itself and the missing key, then returns the proc's return value: # # h = Hash.new { |hash, key| "Default value for #{key}" } # h[:nosuch] # => "Default value for nosuch" @@ -347,13 +347,13 @@ # # ### What's Here # -# First, what's elsewhere. Class Hash: +# First, what's elsewhere. Class `Hash`: # # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). # * Includes [module Enumerable](rdoc-ref:Enumerable@What-27s+Here), which # provides dozens of additional methods. # -# Here, class Hash provides methods that are useful for: +# Here, class `Hash` provides methods that are useful for: # # * [Creating a Hash](rdoc-ref:Hash@Methods+for+Creating+a+Hash) # * [Setting Hash State](rdoc-ref:Hash@Methods+for+Setting+Hash+State) @@ -368,15 +368,15 @@ # Values](rdoc-ref:Hash@Methods+for+Transforming+Keys+and+Values) # * [And more....](rdoc-ref:Hash@Other+Methods) # -# Class Hash also includes methods from module Enumerable. +# Class `Hash` also includes methods from module Enumerable. # -# #### Methods for Creating a Hash +# #### Methods for Creating a `Hash` # # * ::[]: Returns a new hash populated with given objects. # * ::new: Returns a new empty hash. # * ::try_convert: Returns a new hash created from a given object. # -# #### Methods for Setting Hash State +# #### Methods for Setting `Hash` State # # * #compare_by_identity: Sets `self` to consider only identity in comparing # keys. @@ -395,11 +395,11 @@ # * #empty?: Returns whether there are no entries. # * #eql?: Returns whether a given object is equal to `self`. # * #hash: Returns the integer hash code. -# * #has_value?: Returns whether a given object is a value in `self`. -# * #include?, #has_key?, #member?, #key?: Returns whether a given object is a -# key in `self`. -# * #length, #size: Returns the count of entries. -# * #value?: Returns whether a given object is a value in `self`. +# * #has_value? (aliased as #value?): Returns whether a given object is a +# value in `self`. +# * #include? (aliased as #has_key?, #member?, #key?): Returns whether a given +# object is a key in `self`. +# * #size (aliased as #length): Returns the count of entries. # # #### Methods for Comparing # @@ -427,12 +427,12 @@ # # #### Methods for Assigning # -# * #[]=, #store: Associates a given key with a given value. +# * #[]= (aliased as #store): Associates a given key with a given value. # * #merge: Returns the hash formed by merging each given hash into a copy of # `self`. -# * #merge!, #update: Merges each given hash into `self`. -# * #replace: Replaces the entire contents of `self` with the contents of a -# given hash. +# * #update (aliased as #merge!): Merges each given hash into `self`. +# * #replace (aliased as #initialize_copy): Replaces the entire contents of +# `self` with the contents of a given hash. # # #### Methods for Deleting # @@ -442,7 +442,8 @@ # * #compact!: Removes all `nil`-valued entries from `self`. # * #delete: Removes the entry for a given key. # * #delete_if: Removes entries selected by a given block. -# * #filter!, #select!: Keep only those entries selected by a given block. +# * #select! (aliased as #filter!): Keep only those entries selected by a +# given block. # * #keep_if: Keep only those entries selected by a given block. # * #reject!: Removes entries selected by a given block. # * #shift: Removes and returns the first entry. @@ -451,24 +452,26 @@ # # * #compact: Returns a copy of `self` with all `nil`-valued entries removed. # * #except: Returns a copy of `self` with entries removed for specified keys. -# * #filter, #select: Returns a copy of `self` with only those entries -# selected by a given block. +# * #select (aliased as #filter): Returns a copy of `self` with only those +# entries selected by a given block. # * #reject: Returns a copy of `self` with entries removed as specified by a # given block. # * #slice: Returns a hash containing the entries for given keys. # # #### Methods for Iterating -# * #each, #each_pair: Calls a given block with each key-value pair. +# * #each_pair (aliased as #each): Calls a given block with each key-value +# pair. # * #each_key: Calls a given block with each key. # * #each_value: Calls a given block with each value. # # #### Methods for Converting # -# * #inspect, #to_s: Returns a new String containing the hash entries. +# * #inspect (aliased as #to_s): Returns a new String containing the hash +# entries. # * #to_a: Returns a new array of 2-element arrays; each nested array contains # a key-value pair from `self`. -# * #to_h: Returns `self` if a Hash; if a subclass of Hash, returns a Hash -# containing the entries from `self`. +# * #to_h: Returns `self` if a `Hash`; if a subclass of `Hash`, returns a +# `Hash` containing the entries from `self`. # * #to_hash: Returns `self`. # * #to_proc: Returns a proc that maps a given key to its value. # @@ -499,23 +502,23 @@ class Hash[unchecked out K, unchecked out V] < Object # - Hash[ [*2_element_arrays] ] -> new_hash # - Hash[*objects] -> new_hash # --> - # Returns a new Hash object populated with the given objects, if any. See + # Returns a new `Hash` object populated with the given objects, if any. See # Hash::new. # - # With no argument, returns a new empty Hash. + # With no argument, returns a new empty `Hash`. # - # When the single given argument is a Hash, returns a new Hash populated with - # the entries from the given Hash, excluding the default value or proc. + # When the single given argument is a `Hash`, returns a new `Hash` populated + # with the entries from the given `Hash`, excluding the default value or proc. # # h = {foo: 0, bar: 1, baz: 2} # Hash[h] # => {:foo=>0, :bar=>1, :baz=>2} # # When the single given argument is an Array of 2-element Arrays, returns a new - # Hash object wherein each 2-element array forms a key-value entry: + # `Hash` object wherein each 2-element array forms a key-value entry: # # Hash[ [ [:foo, 0], [:bar, 1] ] ] # => {:foo=>0, :bar=>1} # - # When the argument count is an even number; returns a new Hash object wherein + # When the argument count is an even number; returns a new `Hash` object wherein # each successive pair of arguments has become a key-value entry: # # Hash[:foo, 0, :bar, 1] # => {:foo=>0, :bar=>1} @@ -530,14 +533,14 @@ class Hash[unchecked out K, unchecked out V] < Object # rdoc-file=hash.c # - Hash.try_convert(obj) -> obj, new_hash, or nil # --> - # If `obj` is a Hash object, returns `obj`. + # If `obj` is a `Hash` object, returns `obj`. # # Otherwise if `obj` responds to `:to_hash`, calls `obj.to_hash` and returns the # result. # # Returns `nil` if `obj` does not respond to `:to_hash` # - # Raises an exception unless `obj.to_hash` returns a Hash object. + # Raises an exception unless `obj.to_hash` returns a `Hash` object. # def self.try_convert: [U, V] (_ToHash[U, V]) -> ::Hash[U, V] | (untyped) -> (::Hash[untyped, untyped] | nil) @@ -574,7 +577,7 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash == object -> true or false # --> # Returns `true` if all of the following are true: - # * `object` is a Hash object. + # * `object` is a `Hash` object. # * `hash` and `object` have the same keys (regardless of order). # * For each key `key`, `hash[key] == object[key]`. # @@ -825,7 +828,7 @@ class Hash[unchecked out K, unchecked out V] < Object # rdoc-file=hash.c # - hash.default_proc = proc -> proc # --> - # Sets the default proc for `self` to `proc`: (see [Default + # Sets the default proc for `self` to `proc` (see [Default # Values](rdoc-ref:Hash@Default+Values)): # h = {} # h.default_proc # => nil @@ -1034,16 +1037,15 @@ class Hash[unchecked out K, unchecked out V] < Object # # Returns `true` if all of the following are true: - # * `object` is a Hash object. + # * `object` is a `Hash` object. # * `hash` and `object` have the same keys (regardless of order). - # * For each key `key`, `h[key] eql? object[key]`. + # * For each key `key`, `h[key].eql?(object[key])`. # # Otherwise, returns `false`. # - # Equal: # h1 = {foo: 0, bar: 1, baz: 2} # h2 = {foo: 0, bar: 1, baz: 2} # h1.eql? h2 # => true @@ -1056,7 +1058,7 @@ class Hash[unchecked out K, unchecked out V] < Object # rdoc-file=hash.c # - hsh.except(*keys) -> a_hash # --> - # Returns a new Hash excluding entries for the given `keys`: + # Returns a new `Hash` excluding entries for the given `keys`: # h = { a: 100, b: 200, c: 300 } # h.except(:a) #=> {:b=>200, :c=>300} # @@ -1114,8 +1116,8 @@ class Hash[unchecked out K, unchecked out V] < Object | [X] (*K) { (K) -> X } -> ::Array[V | X] # - # Returns a new Hash object whose entries are those for which the block returns - # a truthy value: + # Returns a new `Hash` object whose entries are those for which the block + # returns a truthy value: # h = {foo: 0, bar: 1, baz: 2} # h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1} # @@ -1197,7 +1199,7 @@ class Hash[unchecked out K, unchecked out V] < Object # --> # Returns the Integer hash-code for the hash. # - # Two Hash objects have the same hash-code if their content is the same + # Two `Hash` objects have the same hash-code if their content is the same # (regardless of order): # h1 = {foo: 0, bar: 1, baz: 2} # h2 = {baz: 2, bar: 1, foo: 0} @@ -1232,7 +1234,7 @@ class Hash[unchecked out K, unchecked out V] < Object # rdoc-file=hash.c # - hash.invert -> new_hash # --> - # Returns a new Hash object with the each key-value pair inverted: + # Returns a new `Hash` object with the each key-value pair inverted: # h = {foo: 0, bar: 1, baz: 2} # h1 = h.invert # h1 # => {0=>:foo, 1=>:bar, 2=>:baz} @@ -1309,15 +1311,15 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.merge(*other_hashes) -> new_hash # - hash.merge(*other_hashes) { |key, old_value, new_value| ... } -> new_hash # --> - # Returns the new Hash formed by merging each of `other_hashes` into a copy of + # Returns the new `Hash` formed by merging each of `other_hashes` into a copy of # `self`. # - # Each argument in `other_hashes` must be a Hash. + # Each argument in `other_hashes` must be a `Hash`. # # --- # # With arguments and no block: - # * Returns the new Hash object formed by merging each successive Hash in + # * Returns the new `Hash` object formed by merging each successive `Hash` in # `other_hashes` into `self`. # * Each new-key entry is added at the end. # * Each duplicate-key entry's value overwrites the previous value. @@ -1329,7 +1331,8 @@ class Hash[unchecked out K, unchecked out V] < Object # h.merge(h1, h2) # => {:foo=>0, :bar=>4, :baz=>2, :bat=>6, :bam=>5} # # With arguments and a block: - # * Returns a new Hash object that is the merge of `self` and each given hash. + # * Returns a new `Hash` object that is the merge of `self` and each given + # hash. # * The given hashes are merged left to right. # * Each new-key entry is added at the end. # * For each duplicate key: @@ -1359,7 +1362,7 @@ class Hash[unchecked out K, unchecked out V] < Object # # Merges each of `other_hashes` into `self`; returns `self`. # - # Each argument in `other_hashes` must be a Hash. + # Each argument in `other_hashes` must be a `Hash`. # # With arguments and no block: # * Returns `self`, after the given hashes are merged into it. @@ -1433,7 +1436,7 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.reject {|key, value| ... } -> new_hash # - hash.reject -> new_enumerator # --> - # Returns a new Hash object whose entries are all those from `self` for which + # Returns a new `Hash` object whose entries are all those from `self` for which # the block returns `false` or `nil`: # h = {foo: 0, bar: 1, baz: 2} # h1 = h.reject {|key, value| key.start_with?('b') } @@ -1481,8 +1484,8 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.select {|key, value| ... } -> new_hash # - hash.select -> new_enumerator # --> - # Returns a new Hash object whose entries are those for which the block returns - # a truthy value: + # Returns a new `Hash` object whose entries are those for which the block + # returns a truthy value: # h = {foo: 0, bar: 1, baz: 2} # h.select {|key, value| value < 2 } # => {:foo=>0, :bar=>1} # @@ -1541,7 +1544,7 @@ class Hash[unchecked out K, unchecked out V] < Object # rdoc-file=hash.c # - hash.slice(*keys) -> new_hash # --> - # Returns a new Hash object containing the entries for the given `keys`: + # Returns a new `Hash` object containing the entries for the given `keys`: # h = {foo: 0, bar: 1, baz: 2} # h.slice(:baz, :foo) # => {:baz=>2, :foo=>0} # @@ -1584,12 +1587,13 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.to_h -> self or new_hash # - hash.to_h {|key, value| ... } -> new_hash # --> - # For an instance of Hash, returns `self`. + # For an instance of `Hash`, returns `self`. # - # For a subclass of Hash, returns a new Hash containing the content of `self`. + # For a subclass of `Hash`, returns a new `Hash` containing the content of + # `self`. # - # When a block is given, returns a new Hash object whose content is based on the - # block; the block should return a 2-element Array object specifying the + # When a block is given, returns a new `Hash` object whose content is based on + # the block; the block should return a 2-element Array object specifying the # key-value pair to be included in the returned Array: # h = {foo: 0, bar: 1, baz: 2} # h1 = h.to_h {|key, value| [value, key] } @@ -1635,7 +1639,7 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.transform_keys(hash2) {|other_key| ...} -> new_hash # - hash.transform_keys -> new_enumerator # --> - # Returns a new Hash object; each entry has: + # Returns a new `Hash` object; each entry has: # * A key provided by the block. # * The value from `self`. # @@ -1686,7 +1690,7 @@ class Hash[unchecked out K, unchecked out V] < Object # - hash.transform_values {|value| ... } -> new_hash # - hash.transform_values -> new_enumerator # --> - # Returns a new Hash object; each entry has: + # Returns a new `Hash` object; each entry has: # * A key from `self`. # * A value provided by the block. # @@ -1731,7 +1735,7 @@ class Hash[unchecked out K, unchecked out V] < Object # --> # Merges each of `other_hashes` into `self`; returns `self`. # - # Each argument in `other_hashes` must be a Hash. + # Each argument in `other_hashes` must be a `Hash`. # # With arguments and no block: # * Returns `self`, after the given hashes are merged into it. @@ -1804,34 +1808,42 @@ class Hash[unchecked out K, unchecked out V] < Object private # - # Returns a new empty Hash object. + # Returns a new empty `Hash` object. # # The initial default value and initial default proc for the new hash depend on # which form above was used. See [Default Values](rdoc-ref:Hash@Default+Values). # - # If neither an argument nor a block given, initializes both the default value - # and the default proc to `nil`: + # If neither an argument nor a block is given, initializes both the default + # value and the default proc to `nil`: # h = Hash.new # h.default # => nil # h.default_proc # => nil # - # If argument `default_value` given but no block given, initializes the default - # value to the given `default_value` and the default proc to `nil`: + # If argument `default_value` is given but no block is given, initializes the + # default value to the given `default_value` and the default proc to `nil`: # h = Hash.new(false) # h.default # => false # h.default_proc # => nil # - # If a block given but no argument, stores the block as the default proc and - # sets the default value to `nil`: + # If a block is given but no `default_value`, stores the block as the default + # proc and sets the default value to `nil`: # h = Hash.new {|hash, key| "Default value for #{key}" } # h.default # => nil # h.default_proc.class # => Proc # h[:nosuch] # => "Default value for nosuch" # + # If both a block and a `default_value` are given, raises an `ArgumentError` + # + # If the optional keyword argument `capacity` is given, the hash will be + # allocated with enough capacity to accommodate this many keys without having to + # be resized. + # def initialize: () -> void | (untyped default) -> void | [A, B] () { (Hash[A, B] hash, A key) -> B } -> void diff --git a/core/integer.rbs b/core/integer.rbs index 16b73967de..e7eb88866c 100644 --- a/core/integer.rbs +++ b/core/integer.rbs @@ -16,7 +16,9 @@ # # First, what's elsewhere. Class Integer: # -# * Inherits from [class Numeric](rdoc-ref:Numeric@What-27s+Here). +# * Inherits from [class Numeric](rdoc-ref:Numeric@What-27s+Here) and [class +# Object](rdoc-ref:Object@What-27s+Here). +# * Includes [module Comparable](rdoc-ref:Comparable@What-27s+Here). # # Here, class Integer provides methods for: # @@ -58,6 +60,7 @@ # * #>>: Returns the value of `self` after a rightward bit-shift. # * #[]: Returns a slice of bits from `self`. # * #^: Returns the bitwise EXCLUSIVE OR of `self` and the given value. +# * #|: Returns the bitwise OR of `self` and the given value. # * #ceil: Returns the smallest number greater than or equal to `self`. # * #chr: Returns a 1-character string containing the character represented by # the value of `self`. @@ -79,7 +82,6 @@ # * #to_s (aliased as #inspect): Returns a string containing the place-value # representation of `self` in the given radix. # * #truncate: Returns `self` truncated to the given precision. -# * #|: Returns the bitwise OR of `self` and the given value. # # ### Other # @@ -612,22 +614,40 @@ class Integer < Numeric # rdoc-file=numeric.c # - ceil(ndigits = 0) -> integer # --> - # Returns the smallest number greater than or equal to `self` with a precision - # of `ndigits` decimal digits. - # - # When the precision is negative, the returned value is an integer with at least - # `ndigits.abs` trailing zeros: - # - # 555.ceil(-1) # => 560 - # 555.ceil(-2) # => 600 - # -555.ceil(-2) # => -500 - # 555.ceil(-3) # => 1000 - # - # Returns `self` when `ndigits` is zero or positive. - # - # 555.ceil # => 555 - # 555.ceil(50) # => 555 - # + # Returns an integer that is a "ceiling" value for `self`, + # as specified by the given `ndigits`, + # which must be an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). + # * When `self` is zero, returns zero (regardless of the value of `ndigits`): + # 0.ceil(2) # => 0 + # 0.ceil(-2) # => 0 + # + # * When `self` is non-zero and `ndigits` is non-negative, returns `self`: + # 555.ceil # => 555 + # 555.ceil(50) # => 555 + # + # * When `self` is non-zero and `ndigits` is negative, + # returns a value based on a computed granularity: + # * The granularity is `10 ** ndigits.abs`. + # * The returned value is the smallest multiple of the granularity + # that is greater than or equal to `self`. + # Examples with positive `self`: + # ndigits|Granularity|1234.ceil(ndigits) + # -------|-----------|------------------ + # -1| 10| 1240 + # -2| 100| 1300 + # -3| 1000| 2000 + # -4| 10000| 10000 + # -5| 100000| 100000 + # Examples with negative `self`: + # ndigits|Granularity|-1234.ceil(ndigits) + # -------|-----------|------------------- + # -1| 10| -1230 + # -2| 100| -1200 + # -3| 1000| -1000 + # -4| 10000| 0 + # -5| 100000| 0 # Related: Integer#floor. # def ceil: () -> Integer @@ -720,14 +740,14 @@ class Integer < Numeric # Performs integer division; returns the integer result of dividing `self` by # `numeric`: # - # 4.div(3) # => 1 - # 4.div(-3) # => -2 - # -4.div(3) # => -2 - # -4.div(-3) # => 1 - # 4.div(3.0) # => 1 - # 4.div(Rational(3, 1)) # => 1 + # 4.div(3) # => 1 + # 4.div(-3) # => -2 + # -4.div(3) # => -2 + # -4.div(-3) # => 1 + # 4.div(3.0) # => 1 + # 4.div(Rational(3, 1)) # => 1 # - # Raises an exception if +numeric+ does not have method +div+. + # Raises an exception if `numeric` does not have method `div`. # def div: (Numeric) -> Integer @@ -815,22 +835,40 @@ class Integer < Numeric # rdoc-file=numeric.c # - floor(ndigits = 0) -> integer # --> - # Returns the largest number less than or equal to `self` with a precision of - # `ndigits` decimal digits. - # - # When `ndigits` is negative, the returned value has at least `ndigits.abs` - # trailing zeros: - # - # 555.floor(-1) # => 550 - # 555.floor(-2) # => 500 - # -555.floor(-2) # => -600 - # 555.floor(-3) # => 0 - # - # Returns `self` when `ndigits` is zero or positive. - # - # 555.floor # => 555 - # 555.floor(50) # => 555 - # + # Returns an integer that is a "floor" value for `self`, + # as specified by the given `ndigits`, + # which must be an + # [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). + # * When `self` is zero, returns zero (regardless of the value of `ndigits`): + # 0.floor(2) # => 0 + # 0.floor(-2) # => 0 + # + # * When `self` is non-zero and `ndigits` is non-negative, returns `self`: + # 555.floor # => 555 + # 555.floor(50) # => 555 + # + # * When `self` is non-zero and `ndigits` is negative, + # returns a value based on a computed granularity: + # * The granularity is `10 ** ndigits.abs`. + # * The returned value is the largest multiple of the granularity + # that is less than or equal to `self`. + # Examples with positive `self`: + # ndigits|Granularity|1234.floor(ndigits) + # -------|-----------|------------------- + # -1| 10| 1230 + # -2| 100| 1200 + # -3| 1000| 1000 + # -4| 10000| 0 + # -5| 100000| 0 + # Examples with negative `self`: + # ndigits|Granularity|-1234.floor(ndigits) + # -------|-----------|-------------------- + # -1| 10| -1240 + # -2| 100| -1300 + # -3| 1000| -2000 + # -4| 10000| -10000 + # -5| 100000| -100000 # Related: Integer#ceil. # def floor: (?int digits) -> Integer diff --git a/core/io.rbs b/core/io.rbs index 80e142278e..501538e457 100644 --- a/core/io.rbs +++ b/core/io.rbs @@ -124,6 +124,9 @@ # line number zero); method `rewind` resets the position (and line number) to # zero. # +# These methods discard [buffers](rdoc-ref:IO@Buffering) and the +# Encoding::Converter instances used for that IO. +# # The relevant methods: # # * IO#tell (aliased as `#pos`): Returns the current position (in bytes) in @@ -175,54 +178,62 @@ # # ## Line IO # -# You can read an IO stream line-by-line using these methods: +# Class IO supports line-oriented [input](rdoc-ref:IO@Line+Input) and +# [output](rdoc-ref:IO@Line+Output) # -# * IO#each_line: Reads each remaining line, passing it to the given block. -# * IO#gets: Returns the next line. -# * IO#readline: Like #gets, but raises an exception at end-of-stream. -# * IO#readlines: Returns all remaining lines in an array. +# ### Line Input # -# Each of these reader methods accepts: +# Class IO supports line-oriented input for [files](rdoc-ref:IO@File+Line+Input) +# and [IO streams](rdoc-ref:IO@Stream+Line+Input) # -# * An optional line separator, `sep`; see [Line -# Separator](rdoc-ref:IO@Line+Separator). -# * An optional line-size limit, `limit`; see [Line -# Limit](rdoc-ref:IO@Line+Limit). +# #### File Line Input # -# For each of these reader methods, reading may begin mid-line, depending on the -# stream's position; see [Position](rdoc-ref:IO@Position): +# You can read lines from a file using these methods: # -# f = File.new('t.txt') -# f.pos = 27 -# f.each_line {|line| p line } -# f.close +# * IO.foreach: Reads each line and passes it to the given block. +# * IO.readlines: Reads and returns all lines in an array. # -# Output: +# For each of these methods: +# +# * You can specify [open options](rdoc-ref:IO@Open+Options). +# * Line parsing depends on the effective *line separator*; see [Line +# Separator](rdoc-ref:IO@Line+Separator). +# * The length of each returned line depends on the effective *line limit*; +# see [Line Limit](rdoc-ref:IO@Line+Limit). # -# "rth line\n" -# "Fifth line\n" +# #### Stream Line Input # -# You can write to an IO stream line-by-line using this method: +# You can read lines from an IO stream using these methods: # -# * IO#puts: Writes objects to the stream. +# * IO#each_line: Reads each remaining line, passing it to the given block. +# * IO#gets: Returns the next line. +# * IO#readline: Like #gets, but raises an exception at end-of-stream. +# * IO#readlines: Returns all remaining lines in an array. +# +# For each of these methods: +# +# * Reading may begin mid-line, depending on the stream's *position*; see +# [Position](rdoc-ref:IO@Position). +# * Line parsing depends on the effective *line separator*; see [Line +# Separator](rdoc-ref:IO@Line+Separator). +# * The length of each returned line depends on the effective *line limit*; +# see [Line Limit](rdoc-ref:IO@Line+Limit). # -# ### Line Separator +# ##### Line Separator # -# Each of these methods uses a *line separator*, which is the string that -# delimits lines: +# Each of the [line input methods](rdoc-ref:IO@Line+Input) uses a *line +# separator*: the string that determines what is considered a line; it is +# sometimes called the *input record separator*. # -# * IO.foreach. -# * IO.readlines. -# * IO#each_line. -# * IO#gets. -# * IO#readline. -# * IO#readlines. +# The default line separator is taken from global variable `$/`, whose initial +# value is `"\n"`. # -# The default line separator is the given by the global variable `$/`, whose -# value is by default `"\n"`. The line to be read next is all data from the -# current position to the next line separator: +# Generally, the line to be read next is all data from the current +# [position](rdoc-ref:IO@Position) to the next line separator (but see [Special +# Line Separator Values](rdoc-ref:IO@Special+Line+Separator+Values)): # # f = File.new('t.txt') +# # Method gets with no sep argument returns the next line, according to $/. # f.gets # => "First line\n" # f.gets # => "Second line\n" # f.gets # => "\n" @@ -230,7 +241,7 @@ # f.gets # => "Fifth line\n" # f.close # -# You can specify a different line separator: +# You can use a different line separator by passing argument `sep`: # # f = File.new('t.txt') # f.gets('l') # => "First l" @@ -239,38 +250,45 @@ # f.gets # => "e\n" # f.close # -# There are two special line separators: +# Or by setting global variable `$/`: # -# * `nil`: The entire stream is read into a single string: +# f = File.new('t.txt') +# $/ = 'l' +# f.gets # => "First l" +# f.gets # => "ine\nSecond l" +# f.gets # => "ine\n\nFourth l" +# f.close +# +# ##### Special Line Separator Values +# +# Each of the [line input methods](rdoc-ref:IO@Line+Input) accepts two special +# values for parameter `sep`: +# +# * `nil`: The entire stream is to be read ("slurped") into a single string: # # f = File.new('t.txt') # f.gets(nil) # => "First line\nSecond line\n\nFourth line\nFifth line\n" # f.close # -# * `''` (the empty string): The next "paragraph" is read (paragraphs being -# separated by two consecutive line separators): +# * `''` (the empty string): The next "paragraph" is to be read (paragraphs +# being separated by two consecutive line separators): # # f = File.new('t.txt') # f.gets('') # => "First line\nSecond line\n\n" # f.gets('') # => "Fourth line\nFifth line\n" # f.close # -# ### Line Limit +# ##### Line Limit # -# Each of these methods uses a *line limit*, which specifies that the number of -# bytes returned may not be (much) longer than the given `limit`; +# Each of the [line input methods](rdoc-ref:IO@Line+Input) uses an integer *line +# limit*, which restricts the number of bytes that may be returned. (A +# multi-byte character will not be split, and so a returned line may be slightly +# longer than the limit). # -# * IO.foreach. -# * IO.readlines. -# * IO#each_line. -# * IO#gets. -# * IO#readline. -# * IO#readlines. +# The default limit value is `-1`; any negative limit value means that there is +# no limit. # -# A multi-byte character will not be split, and so a line may be slightly longer -# than the given limit. -# -# If `limit` is not given, the line is determined only by `sep`. +# If there is no limit, the line is determined only by `sep`. # # # Text with 1-byte characters. # File.open('t.txt') {|f| f.gets(1) } # => "F" @@ -288,30 +306,28 @@ # File.open('t.rus') {|f| f.gets(3).size } # => 2 # File.open('t.rus') {|f| f.gets(4).size } # => 2 # -# ### Line Separator and Line Limit +# ##### Line Separator and Line Limit # # With arguments `sep` and `limit` given, combines the two behaviors: # # * Returns the next line as determined by line separator `sep`. -# * But returns no more bytes than are allowed by the limit. +# * But returns no more bytes than are allowed by the limit `limit`. # # Example: # # File.open('t.txt') {|f| f.gets('li', 20) } # => "First li" # File.open('t.txt') {|f| f.gets('li', 2) } # => "Fi" # -# ### Line Number -# -# A readable IO stream has a non-negative integer *line number*. +# ##### Line Number # -# The relevant methods: +# A readable IO stream has a non-negative integer *line number*: # # * IO#lineno: Returns the line number. # * IO#lineno=: Resets and returns the line number. # # Unless modified by a call to method IO#lineno=, the line number is the number -# of lines read by certain line-oriented methods, according to the given line -# separator `sep`: +# of lines read by certain line-oriented methods, according to the effective +# [line separator](rdoc-ref:IO@Line+Separator): # # * IO.foreach: Increments the line number on each call to the block. # * IO#each_line: Increments the line number on each call to the block. @@ -401,6 +417,12 @@ # $. # => 5 # f.close # +# ### Line Output +# +# You can write to an IO stream line-by-line using this method: +# +# * IO#puts: Writes objects to the stream. +# # ## Character IO # # You can process an IO stream character-by-character using these methods: @@ -412,6 +434,7 @@ # * IO#putc: Writes a character to the stream. # * IO#each_char: Reads each remaining character in the stream, passing the # character to the given block. +# # ## Byte IO # # You can process an IO stream byte-by-byte using these methods: @@ -704,6 +727,9 @@ class IO < Object # If the stream was opened by IO.popen, sets global variable `$?` (child exit # status). # + # It is not an error to close an IO object that has already been closed. It just + # returns nil. + # # Example: # # IO.popen('ruby', 'r+') do |pipe| @@ -1100,11 +1126,8 @@ class IO < Object # File.open('t.txt') {|f| f.gets(11) } # => "First line\n" # File.open('t.txt') {|f| f.gets(12) } # => "First line\n" # - # With arguments `sep` and `limit` given, combines the two behaviors: - # - # * Returns the next line as determined by line separator `sep`, or `nil` if - # none. - # * But returns no more bytes than are allowed by the limit. + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword argument `chomp` specifies whether line separators are to be # omitted: @@ -1644,10 +1667,8 @@ class IO < Object # # => ["First li", "ne\n", "Second l", "ine\n", "\n", "Fourth l", "ine\n", "Fifth li", "ne\n"] # f.close # - # With arguments `sep` and `limit` given, combines the two behaviors: - # - # * Returns lines as determined by line separator `sep`. - # * But returns no more bytes in a line than are allowed by the limit. + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword argument `chomp` specifies whether line separators are to be # omitted: @@ -2545,6 +2566,7 @@ class IO < Object # # With argument `limit` given, parses lines as determined by the default line # separator and the given line-length limit (see [Line + # Separator](rdoc-ref:IO@Line+Separator) and [Line # Limit](rdoc-ref:IO@Line+Limit)): # # File.foreach('t.txt', 7) {|line| p line } @@ -2561,9 +2583,8 @@ class IO < Object # "Fourth l" # "line\n" # - # With arguments `sep` and `limit` given, parses lines as determined by the - # given line separator and the given line-length limit (see [Line Separator and - # Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)): + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword arguments `opts` specify: # @@ -2733,14 +2754,14 @@ class IO < Object # # With argument `limit` given, parses lines as determined by the default line # separator and the given line-length limit (see [Line - # Limit](rdoc-ref:IO@Line+Limit)): + # Separator](rdoc-ref:IO@Line+Separator) and [Line + # Limit](rdoc-ref:IO@Line+Limit): # # IO.readlines('t.txt', 7) # # => ["First l", "ine\n", "Second ", "line\n", "\n", "Third l", "ine\n", "Fourth ", "line\n"] # - # With arguments `sep` and `limit` given, parses lines as determined by the - # given line separator and the given line-length limit (see [Line Separator and - # Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)): + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword arguments `opts` specify: # @@ -2763,7 +2784,8 @@ class IO < Object # Each of the arguments `read_ios`, `write_ios`, and `error_ios` is an array of # IO objects. # - # Argument `timeout` is an integer timeout interval in seconds. + # Argument `timeout` is a numeric value (such as integer or float) timeout + # interval in seconds. # # The method monitors the IO objects given in all three arrays, waiting for some # to be ready; returns a 3-element array whose elements are: @@ -3062,10 +3084,8 @@ class IO < Object # "Fifth li" # "ne\n" # - # With arguments `sep` and `limit` given, combines the two behaviors: - # - # * Calls with the next line as determined by line separator `sep`. - # * But returns no more bytes than are allowed by the limit. + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword argument `chomp` specifies whether line separators are to be # omitted: @@ -3166,10 +3186,8 @@ class IO < Object # "Fifth li" # "ne\n" # - # With arguments `sep` and `limit` given, combines the two behaviors: - # - # * Calls with the next line as determined by line separator `sep`. - # * But returns no more bytes than are allowed by the limit. + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword argument `chomp` specifies whether line separators are to be # omitted: diff --git a/core/io/buffer.rbs b/core/io/buffer.rbs index fea8cd9d77..5087d2615a 100644 --- a/core/io/buffer.rbs +++ b/core/io/buffer.rbs @@ -41,30 +41,28 @@ class IO # # Buffer from string: # - # string = 'buffer' - # buffer = IO::Buffer.for(string) - # # => - # # # - # # ... - # buffer - # # => - # # # - # # 0x00000000 64 61 74 61 buffer + # string = 'data' + # IO::Buffer.for(string) do |buffer| + # buffer + # # => + # # # + # # 0x00000000 64 61 74 61 data # - # buffer.get_string(2) # read content starting from offset 2 - # # => "ta" - # buffer.set_string('---', 1) # write content, starting from offset 1 - # # => 3 - # buffer - # # => - # # # - # # 0x00000000 64 2d 2d 2d d--- - # string # original string changed, too - # # => "d---" + # buffer.get_string(2) # read content starting from offset 2 + # # => "ta" + # buffer.set_string('---', 1) # write content, starting from offset 1 + # # => 3 + # buffer + # # => + # # # + # # 0x00000000 64 2d 2d 2d d--- + # string # original string changed, too + # # => "d---" + # end # # Buffer from file: # - # File.write('test.txt', 'test buffer') + # File.write('test.txt', 'test data') # # => 9 # buffer = IO::Buffer.map(File.open('test.txt')) # # => @@ -81,7 +79,7 @@ class IO # buffer.set_string('---', 1) # # => 3 -- bytes written # File.read('test.txt') - # # => "t--- buffer" + # # => "t--- data" # # **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 @@ -198,29 +196,29 @@ class IO # --> # Fill buffer with `value`, starting with `offset` and going for `length` bytes. # - # buffer = IO::Buffer.for('test') + # buffer = IO::Buffer.for('test').dup # # => - # # + # # # # 0x00000000 74 65 73 74 test # # buffer.clear # # => - # # + # # # # 0x00000000 00 00 00 00 .... # # buf.clear(1) # fill with 1 # # => - # # + # # # # 0x00000000 01 01 01 01 .... # # buffer.clear(2, 1, 2) # fill with 2, starting from offset 1, for 2 bytes # # => - # # + # # # # 0x00000000 01 02 02 01 .... # # buffer.clear(2, 1) # fill with 2, starting from offset 1 # # => - # # + # # # # 0x00000000 01 02 02 02 .... # def clear: (?Integer value, ?Integer offset, ?Integer length) -> self @@ -230,7 +228,7 @@ class IO # - copy(source, [offset, [length, [source_offset]]]) -> size # --> # Efficiently copy from a source IO::Buffer into the buffer, at `offset` using - # `memcpy`. For copying String instances, see #set_string. + # `memmove`. For copying String instances, see #set_string. # # buffer = IO::Buffer.new(32) # # => @@ -248,13 +246,14 @@ class IO # # #copy can be used to put buffer into strings associated with buffer: # - # string= "buffer: " - # # => "buffer: " - # buffer = IO::Buffer.for(string) - # buffer.copy(IO::Buffer.for("test"), 5) + # string = "data: " + # # => "data: " + # buffer = IO::Buffer.for(string) do |buffer| + # buffer.copy(IO::Buffer.for("test"), 5) + # end # # => 4 # string - # # => "buffer:test" + # # => "data:test" # # Attempt to copy into a read-only buffer will fail: # @@ -278,6 +277,20 @@ class IO # buffer.copy(IO::Buffer.for('test'), 0) # # in `copy': Specified offset+length is bigger than the buffer size! (ArgumentError) # + # It is safe to copy between memory regions that overlaps each other. In such + # case, the data is copied as if the data was first copied from the source + # buffer to a temporary buffer, and then copied from the temporary buffer to the + # destination buffer. + # + # buffer = IO::Buffer.new(10) + # buffer.set_string("0123456789") + # buffer.copy(buffer, 3, 7) + # # => 7 + # buffer + # # => + # # # + # # 0x00000000 30 31 32 30 31 32 33 34 35 36 0120123456 + # def copy: (Buffer source, ?Integer offset, ?Integer length, ?Integer source_offset) -> Integer # # Efficiently copy from a source String into the buffer, at `offset` using - # `memcpy`. + # `memmove`. # # buf = IO::Buffer.new(8) # # => @@ -736,7 +749,7 @@ class IO # bounds. # # string = 'test' - # buffer = IO::Buffer.for(string) + # buffer = IO::Buffer.for(string).dup # # slice = buffer.slice # # => @@ -763,13 +776,9 @@ class IO # # it is also visible at position 1 of the original buffer # buffer # # => - # # # + # # # # # 0x00000000 74 6f 73 74 tost # - # # ...and original string - # string - # # => tost - # def slice: (Integer offset, Integer length) -> Buffer # # Returns *arg* converted to a float. Numeric types are converted directly, and - # with exception to String and `nil` the rest are converted using *arg*`.to_f`. - # Converting a String with invalid characters will result in a ArgumentError. - # Converting `nil` generates a TypeError. Exceptions can be suppressed by + # with exception to String and `nil`, the rest are converted using *arg*`.to_f`. + # Converting a String with invalid characters will result in an ArgumentError. + # Converting `nil` generates a TypeError. Exceptions can be suppressed by # passing `exception: false`. # # Float(1) #=> 1.0 @@ -538,22 +538,22 @@ module Kernel : BasicObject # # With a non-zero `base`, `object` must be a string or convertible to a string. # - # #### numeric objects + # #### Numeric objects # - # With integer argument `object` given, returns `object`: + # With an integer argument `object` given, returns `object`: # # Integer(1) # => 1 # Integer(-1) # => -1 # - # With floating-point argument `object` given, returns `object` truncated to an - # integer: + # With a floating-point argument `object` given, returns `object` truncated to + # an integer: # # Integer(1.9) # => 1 # Rounds toward zero. # Integer(-1.9) # => -1 # Rounds toward zero. # - # #### string objects + # #### String objects # - # With string argument `object` and zero `base` given, returns `object` + # With a string argument `object` and zero `base` given, returns `object` # converted to an integer in base 10: # # Integer('100') # => 100 @@ -563,7 +563,7 @@ module Kernel : BasicObject # the actual base (radix indicator): # # Integer('0100') # => 64 # Leading '0' specifies base 8. - # Integer('0b100') # => 4 # Leading '0b', specifies base 2. + # Integer('0b100') # => 4 # Leading '0b' specifies base 2. # Integer('0x100') # => 256 # Leading '0x' specifies base 16. # # With a positive `base` (in range 2..36) given, returns `object` converted to @@ -574,7 +574,7 @@ module Kernel : BasicObject # Integer('-100', 16) # => -256 # # With a negative `base` (in range -36..-2) given, returns `object` converted to - # an integer in the radix indicator if exists or `-base`: + # the radix indicator if it exists or `base`: # # Integer('0x100', -2) # => 256 # Integer('100', -2) # => 4 @@ -583,7 +583,7 @@ module Kernel : BasicObject # Integer('0o100', -10) # => 64 # Integer('100', -10) # => 100 # - # `base` -1 is equal the -10 case. + # `base` -1 is equivalent to the -10 case. # # When converting strings, surrounding whitespace and embedded underscores are # allowed and ignored: @@ -591,7 +591,7 @@ module Kernel : BasicObject # Integer(' 100 ') # => 100 # Integer('-1_0_0', 16) # => -256 # - # #### other classes + # #### Other classes # # Examples with `object` of various other classes: # @@ -599,13 +599,13 @@ module Kernel : BasicObject # Integer(Complex(2, 0)) # => 2 # Imaginary part must be zero. # Integer(Time.now) # => 1650974042 # - # #### keywords + # #### Keywords # - # With optional keyword argument `exception` given as `true` (the default): + # With the optional keyword argument `exception` given as `true` (the default): # # * Raises TypeError if `object` does not respond to `to_int` or `to_i`. # * Raises TypeError if `object` is `nil`. - # * Raise ArgumentError if `object` is an invalid string. + # * Raises ArgumentError if `object` is an invalid string. # # With `exception` given as `false`, an exception of any kind is suppressed and # `nil` is returned. @@ -769,11 +769,10 @@ module Kernel : BasicObject # rdoc-file=load.c # - autoload(const, filename) -> nil # --> - # Registers _filename_ to be loaded (using Kernel::require) - # the first time that _const_ (which may be a String or - # a symbol) is accessed. + # Registers *filename* to be loaded (using Kernel::require) the first time that + # *const* (which may be a String or a symbol) is accessed. # - # autoload(:MyModule, "/usr/local/lib/modules/my_module.rb") + # autoload(:MyModule, "/usr/local/lib/modules/my_module.rb") # # If *const* is defined as autoload, the file name to be loaded is replaced with # *filename*. If *const* is defined but not as autoload, does nothing. @@ -784,11 +783,24 @@ module Kernel : BasicObject # rdoc-file=load.c # - autoload?(name, inherit=true) -> String or nil # --> - # Returns *filename* to be loaded if *name* is registered as `autoload`. + # Returns *filename* to be loaded if *name* is registered as `autoload` in the + # current namespace or one of its ancestors. # # autoload(:B, "b") # autoload?(:B) #=> "b" # + # module C + # autoload(:D, "d") + # autoload?(:D) #=> "d" + # autoload?(:B) #=> nil + # end + # + # class E + # autoload(:F, "f") + # autoload?(:F) #=> "f" + # autoload?(:B) #=> "b" + # end + # def self?.autoload?: (interned name) -> String? # - # With no arguments, raises the exception in `$!` or raises a RuntimeError if - # `$!` is `nil`. With a single `String` argument, raises a `RuntimeError` with - # the string as a message. Otherwise, the first parameter should be an - # `Exception` class (or another object that returns an `Exception` object when - # sent an `exception` message). The optional second parameter sets the message - # associated with the exception (accessible via Exception#message), and the - # third parameter is an array of callback information (accessible via - # Exception#backtrace). The `cause` of the generated exception (accessible via - # Exception#cause) is automatically set to the "current" exception (`$!`), if - # any. An alternative value, either an `Exception` object or `nil`, can be - # specified via the `:cause` argument. - # - # Exceptions are caught by the `rescue` clause of `begin...end` blocks. - # - # raise "Failed to create socket" - # raise ArgumentError, "No parameters", caller + # Raises an exception; see [Exceptions](rdoc-ref:exceptions.md). + # + # Argument `exception` sets the class of the new exception; it should be class + # Exception or one of its subclasses (most commonly, RuntimeError or + # StandardError), or an instance of one of those classes: + # + # begin + # raise(StandardError) + # rescue => x + # p x.class + # end + # # => StandardError + # + # Argument `message` sets the stored message in the new exception, which may be + # retrieved by method Exception#message; the message must be a + # [string-convertible + # object](rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects) or + # `nil`: + # + # begin + # raise(StandardError, 'Boom') + # rescue => x + # p x.message + # end + # # => "Boom" + # + # If argument `message` is not given, the message is the exception class name. + # + # See [Messages](rdoc-ref:exceptions.md@Messages). + # + # Argument `backtrace` sets the stored backtrace in the new exception, which may + # be retrieved by method Exception#backtrace; the backtrace must be an array of + # strings or `nil`: + # + # begin + # raise(StandardError, 'Boom', %w[foo bar baz]) + # rescue => x + # p x.backtrace + # end + # # => ["foo", "bar", "baz"] + # + # If argument `backtrace` is not given, the backtrace is set according to an + # array of Thread::Backtrace::Location objects, as derived from the call stack. + # + # See [Backtraces](rdoc-ref:exceptions.md@Backtraces). + # + # Keyword argument `cause` sets the stored cause in the new exception, which may + # be retrieved by method Exception#cause; the cause must be an exception object + # (Exception or one of its subclasses), or `nil`: + # + # begin + # raise(StandardError, cause: RuntimeError.new) + # rescue => x + # p x.cause + # end + # # => # + # + # If keyword argument `cause` is not given, the cause is the value of `$!`. + # + # See [Cause](rdoc-ref:exceptions.md@Cause). + # + # In the alternate calling sequence, where argument `exception` *not* given, + # raises a new exception of the class given by `$!`, or of class RuntimeError if + # `$!` is `nil`: + # + # begin + # raise + # rescue => x + # p x + # end + # # => RuntimeError + # + # With argument `exception` not given, argument `message` and keyword argument + # `cause` may be given, but argument `backtrace` may not be given. # def self?.fail: () -> bot | (string message, ?cause: Exception?) -> bot @@ -918,29 +988,83 @@ module Kernel : BasicObject # - # With no arguments, raises the exception in `$!` or raises a RuntimeError if - # `$!` is `nil`. With a single `String` argument, raises a `RuntimeError` with - # the string as a message. Otherwise, the first parameter should be an - # `Exception` class (or another object that returns an `Exception` object when - # sent an `exception` message). The optional second parameter sets the message - # associated with the exception (accessible via Exception#message), and the - # third parameter is an array of callback information (accessible via - # Exception#backtrace). The `cause` of the generated exception (accessible via - # Exception#cause) is automatically set to the "current" exception (`$!`), if - # any. An alternative value, either an `Exception` object or `nil`, can be - # specified via the `:cause` argument. - # - # Exceptions are caught by the `rescue` clause of `begin...end` blocks. - # - # raise "Failed to create socket" - # raise ArgumentError, "No parameters", caller + # - raise(exception, message = exception.to_s, backtrace = nil, cause: $!) + # - raise(message = nil, cause: $!) + # --> + # Raises an exception; see [Exceptions](rdoc-ref:exceptions.md). + # + # Argument `exception` sets the class of the new exception; it should be class + # Exception or one of its subclasses (most commonly, RuntimeError or + # StandardError), or an instance of one of those classes: + # + # begin + # raise(StandardError) + # rescue => x + # p x.class + # end + # # => StandardError + # + # Argument `message` sets the stored message in the new exception, which may be + # retrieved by method Exception#message; the message must be a + # [string-convertible + # object](rdoc-ref:implicit_conversion.rdoc@String-Convertible+Objects) or + # `nil`: + # + # begin + # raise(StandardError, 'Boom') + # rescue => x + # p x.message + # end + # # => "Boom" + # + # If argument `message` is not given, the message is the exception class name. + # + # See [Messages](rdoc-ref:exceptions.md@Messages). + # + # Argument `backtrace` sets the stored backtrace in the new exception, which may + # be retrieved by method Exception#backtrace; the backtrace must be an array of + # strings or `nil`: + # + # begin + # raise(StandardError, 'Boom', %w[foo bar baz]) + # rescue => x + # p x.backtrace + # end + # # => ["foo", "bar", "baz"] + # + # If argument `backtrace` is not given, the backtrace is set according to an + # array of Thread::Backtrace::Location objects, as derived from the call stack. + # + # See [Backtraces](rdoc-ref:exceptions.md@Backtraces). + # + # Keyword argument `cause` sets the stored cause in the new exception, which may + # be retrieved by method Exception#cause; the cause must be an exception object + # (Exception or one of its subclasses), or `nil`: + # + # begin + # raise(StandardError, cause: RuntimeError.new) + # rescue => x + # p x.cause + # end + # # => # + # + # If keyword argument `cause` is not given, the cause is the value of `$!`. + # + # See [Cause](rdoc-ref:exceptions.md@Cause). + # + # In the alternate calling sequence, where argument `exception` *not* given, + # raises a new exception of the class given by `$!`, or of class RuntimeError if + # `$!` is `nil`: + # + # begin + # raise + # rescue => x + # p x + # end + # # => RuntimeError + # + # With argument `exception` not given, argument `message` and keyword argument + # `cause` may be given, but argument `backtrace` may not be given. # alias raise fail @@ -1033,10 +1157,10 @@ module Kernel : BasicObject # will be raised. # # If the optional *wrap* parameter is `true`, the loaded script will be executed - # under an anonymous module, protecting the calling program's global namespace. - # If the optional *wrap* parameter is a module, the loaded script will be - # executed under the given module. In no circumstance will any local variables - # in the loaded file be propagated to the loading environment. + # under an anonymous module. If the optional *wrap* parameter is a module, the + # loaded script will be executed under the given module. In no circumstance will + # any local variables in the loaded file be propagated to the loading + # environment. # def self?.load: (String filename, ?Module | bool) -> bool @@ -1056,8 +1180,8 @@ module Kernel : BasicObject # # ... # end # - # StopIteration raised in the block breaks the loop. In this case, loop returns - # the "result" value stored in the exception. + # A StopIteration raised in the block breaks the loop. In this case, loop + # returns the "result" value stored in the exception. # # enum = Enumerator.new { |y| # y << "one" @@ -1263,7 +1387,7 @@ module Kernel : BasicObject # --> # prints arguments in pretty form. # - # pp returns argument(s). + # `#pp` returns argument(s). # def self?.pp: [T] (T arg0) -> T | (untyped, untyped, *untyped) -> Array[untyped] @@ -1363,8 +1487,8 @@ module Kernel : BasicObject # $cat t.txt | ruby -e "p readlines 12" # ["First line\n", "Second line\n", "\n", "Fourth line\n", "Fifth line\n"] # - # With arguments `sep` and `limit` given, combines the two behaviors; see [Line - # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit). + # With arguments `sep` and `limit` given, combines the two behaviors (see [Line + # Separator and Line Limit](rdoc-ref:IO@Line+Separator+and+Line+Limit)). # # Optional keyword argument `chomp` specifies whether line separators are to be # omitted: @@ -1418,7 +1542,8 @@ module Kernel : BasicObject # Each of the arguments `read_ios`, `write_ios`, and `error_ios` is an array of # IO objects. # - # Argument `timeout` is an integer timeout interval in seconds. + # Argument `timeout` is a numeric value (such as integer or float) timeout + # interval in seconds. # # The method monitors the IO objects given in all three arrays, waiting for some # to be ready; returns a 3-element array whose elements are: @@ -1595,59 +1720,69 @@ module Kernel : BasicObject # - # Uses the character `cmd` to perform various tests on `file1` (first table - # below) or on `file1` and `file2` (second table). - # - # File tests on a single file: - # - # Cmd Returns Meaning - # "A" | Time | Last access time for file1 - # "b" | boolean | True if file1 is a block device - # "c" | boolean | True if file1 is a character device - # "C" | Time | Last change time for file1 - # "d" | boolean | True if file1 exists and is a directory - # "e" | boolean | True if file1 exists - # "f" | boolean | True if file1 exists and is a regular file - # "g" | boolean | True if file1 has the setgid bit set - # "G" | boolean | True if file1 exists and has a group - # | | ownership equal to the caller's group - # "k" | boolean | True if file1 exists and has the sticky bit set - # "l" | boolean | True if file1 exists and is a symbolic link - # "M" | Time | Last modification time for file1 - # "o" | boolean | True if file1 exists and is owned by - # | | the caller's effective uid - # "O" | boolean | True if file1 exists and is owned by - # | | the caller's real uid - # "p" | boolean | True if file1 exists and is a fifo - # "r" | boolean | True if file1 is readable by the effective - # | | uid/gid of the caller - # "R" | boolean | True if file is readable by the real - # | | uid/gid of the caller - # "s" | int/nil | If file1 has nonzero size, return the size, - # | | otherwise return nil - # "S" | boolean | True if file1 exists and is a socket - # "u" | boolean | True if file1 has the setuid bit set - # "w" | boolean | True if file1 exists and is writable by - # | | the effective uid/gid - # "W" | boolean | True if file1 exists and is writable by - # | | the real uid/gid - # "x" | boolean | True if file1 exists and is executable by - # | | the effective uid/gid - # "X" | boolean | True if file1 exists and is executable by - # | | the real uid/gid - # "z" | boolean | True if file1 exists and has a zero length - # - # Tests that take two files: - # - # "-" | boolean | True if file1 and file2 are identical - # "=" | boolean | True if the modification times of file1 - # | | and file2 are equal - # "<" | boolean | True if the modification time of file1 - # | | is prior to that of file2 - # ">" | boolean | True if the modification time of file1 - # | | is after that of file2 + # - test(char, path0, path1 = nil) -> object + # --> + # Performs a test on one or both of the *filesystem entities* at the given paths + # `path0` and `path1`: + # * Each path `path0` or `path1` points to a file, directory, device, pipe, + # etc. + # * Character `char` selects a specific test. + # The tests: + # * Each of these tests operates only on the entity at `path0`, + # and returns `true` or `false`; + # for a non-existent entity, returns `false` (does not raise exception): + # Character |Test + # ------------|------------------------------------------------------------------------- + # 'b'|Whether the entity is a block device. + # 'c'|Whether the entity is a character device. + # 'd'|Whether the entity is a directory. + # 'e'|Whether the entity is an existing entity. + # 'f'|Whether the entity is an existing regular file. + # 'g'|Whether the entity's setgid bit is set. + # 'G'|Whether the entity's group ownership is equal to the caller's. + # 'k'|Whether the entity's sticky bit is set. + # 'l'|Whether the entity is a symbolic link. + # 'o'|Whether the entity is owned by the caller's effective uid. + # 'O'|Like 'o', but uses the real uid (not the effective uid). + # 'p'|Whether the entity is a FIFO device (named pipe). + # 'r'|Whether the entity is readable by the caller's effective uid/gid. + # 'R'|Like 'r', but uses the real uid/gid (not the effective uid/gid). + # 'S'|Whether the entity is a socket. + # 'u'|Whether the entity's setuid bit is set. + # 'w'|Whether the entity is writable by the caller's effective uid/gid. + # 'W'|Like 'w', but uses the real uid/gid (not the effective uid/gid). + # 'x'|Whether the entity is executable by the caller's effective uid/gid. + # 'X'|Like 'x', but uses the real uid/gid (not the effective uid/git). + # 'z'|Whether the entity exists and is of length zero. + # * This test operates only on the entity at `path0`, + # and returns an integer size or `nil`: + # Character |Test + # ------------|-------------------------------------------------------------------------------------------- + # 's'|Returns positive integer size if the entity exists and has non-zero length, +nil+ otherwise. + # * Each of these tests operates only on the entity at `path0`, + # and returns a Time object; + # raises an exception if the entity does not exist: + # Character |Test + # ------------|-------------------------------------- + # 'A'|Last access time for the entity. + # 'C'|Last change time for the entity. + # 'M'|Last modification time for the entity. + # * Each of these tests operates on the modification time (`mtime`) + # of each of the entities at `path0` and `path1`, + # and returns a `true` or `false`; + # returns `false` if either entity does not exist: + # Character |Test + # ------------|--------------------------------------------------------------- + # '<'|Whether the `mtime` at `path0` is less than that at `path1`. + # '='|Whether the `mtime` at `path0` is equal to that at `path1`. + # '>'|Whether the `mtime` at `path0` is greater than that at `path1`. + # * This test operates on the content of each of the entities at `path0` and + # `path1`, + # and returns a `true` or `false`; + # returns `false` if either entity does not exist: + # Character |Test + # ------------|--------------------------------------------- + # '-'|Whether the entities exist and are identical. # def self?.test: (String | Integer cmd, String | IO file1, ?String | IO file2) -> (TrueClass | FalseClass | Time | nil | Integer) @@ -1698,8 +1833,7 @@ module Kernel : BasicObject # baz.rb:6: warning: invalid call to foo # # If `category` keyword argument is given, passes the category to - # `Warning.warn`. The category given must be be one of the following - # categories: + # `Warning.warn`. The category given must be one of the following categories: # # :deprecated # : Used for warning for deprecated functionality that may be removed in the @@ -1708,6 +1842,10 @@ module Kernel : BasicObject # :experimental # : Used for experimental features that may change in future releases. # + # :performance + # : Used for warning about APIs or pattern that have negative performance + # impact + # def self?.warn: (*_ToS msg, ?uplevel: int?, ?category: Warning::category?) -> nil # - # Yields self to the block, and then returns self. The primary purpose of this + # Yields self to the block and then returns self. The primary purpose of this # method is to "tap into" a method chain, in order to perform operations on # intermediate results within the chain. # @@ -2878,11 +3011,8 @@ module Kernel : BasicObject # - # Yields self to the block and returns the result of the block. - # - # "my string".yield_self {|s| s.upcase } #=> "MY STRING" # def yield_self: () -> Enumerator[self, untyped] | [T] () { (self) -> T } -> T @@ -2895,32 +3025,23 @@ module Kernel : BasicObject # # 3.next.then {|x| x**x }.to_s #=> "256" # - # Good usage for `then` is value piping in method chains: + # A good use of `then` is value piping in method chains: # # require 'open-uri' # require 'json' # - # construct_url(arguments). - # then {|url| URI(url).read }. - # then {|response| JSON.parse(response) } + # construct_url(arguments) + # .then {|url| URI(url).read } + # .then {|response| JSON.parse(response) } # - # When called without block, the method returns `Enumerator`, which can be used, - # for example, for conditional circuit-breaking: + # When called without a block, the method returns an `Enumerator`, which can be + # used, for example, for conditional circuit-breaking: # - # # meets condition, no-op + # # Meets condition, no-op # 1.then.detect(&:odd?) # => 1 - # # does not meet condition, drop value + # # Does not meet condition, drop value # 2.then.detect(&:odd?) # => nil # - # Good usage for `then` is value piping in method chains: - # - # require 'open-uri' - # require 'json' - # - # construct_url(arguments). - # then {|url| URI(url).read }. - # then {|response| JSON.parse(response) } - # alias then yield_self private diff --git a/core/module.rbs b/core/module.rbs index de4bdcb0e7..144a06c7bc 100644 --- a/core/module.rbs +++ b/core/module.rbs @@ -315,14 +315,14 @@ class Module < Object # rdoc-file=load.c # - mod.autoload(const, filename) -> nil # --> - # Registers _filename_ to be loaded (using Kernel::require) - # the first time that _const_ (which may be a String or - # a symbol) is accessed in the namespace of _mod_. + # Registers *filename* to be loaded (using Kernel::require) the first time that + # *const* (which may be a String or a symbol) is accessed in the namespace of + # *mod*. # - # module A - # end - # A.autoload(:B, "b") - # A::B.doit # autoloads "b" + # module A + # end + # A.autoload(:B, "b") + # A::B.doit # autoloads "b" # # If *const* in *mod* is defined as autoload, the file name to be loaded is # replaced with *filename*. If *const* is defined but not as autoload, does @@ -574,7 +574,7 @@ class Module < Object # --> # Invoked when a reference is made to an undefined constant in *mod*. It is # passed a symbol for the undefined constant, and returns a value to be used for - # that constant. The following code is an example of the same: + # that constant. For example, consider: # # def Foo.const_missing(name) # name # return the constant name as Symbol @@ -582,22 +582,27 @@ class Module < Object # # Foo::UNDEFINED_CONST #=> :UNDEFINED_CONST: symbol returned # - # In the next example when a reference is made to an undefined constant, it - # attempts to load a file whose name is the lowercase version of the constant - # (thus class `Fred` is assumed to be in file `fred.rb`). If found, it returns - # the loaded class. It therefore implements an autoload feature similar to - # Kernel#autoload and Module#autoload. + # As the example above shows, `const_missing` is not required to create the + # missing constant in *mod*, though that is often a side-effect. The caller gets + # its return value when triggered. If the constant is also defined, further + # lookups won't hit `const_missing` and will return the value stored in the + # constant as usual. Otherwise, `const_missing` will be invoked again. + # + # In the next example, when a reference is made to an undefined constant, + # `const_missing` attempts to load a file whose path is the lowercase version of + # the constant name (thus class `Fred` is assumed to be in file `fred.rb`). If + # defined as a side-effect of loading the file, the method returns the value + # stored in the constant. This implements an autoload feature similar to + # Kernel#autoload and Module#autoload, though it differs in important ways. # # def Object.const_missing(name) # @looked_for ||= {} # str_name = name.to_s - # raise "Class not found: #{name}" if @looked_for[str_name] + # raise "Constant not found: #{name}" if @looked_for[str_name] # @looked_for[str_name] = 1 # file = str_name.downcase # require file - # klass = const_get(name) - # return klass if klass - # raise "Class not found: #{name}" + # const_get(name, false) # end # def const_missing: (Symbol arg0) -> untyped @@ -1155,9 +1160,9 @@ class Module < Object # - # Returns the name of the module *mod*. Returns nil for anonymous modules. + # Returns the name of the module *mod*. Returns `nil` for anonymous modules. # def name: () -> String? @@ -1482,7 +1487,7 @@ class Module < Object # rdoc-file=eval.c # - refinements -> array # --> - # Returns an array of modules defined within the receiver. + # Returns an array of `Refinement` defined within the receiver. # # module A # refine Integer do @@ -1549,8 +1554,8 @@ class Module < Object # of the module and the values that are related to it, such as instances, # constants, and methods. # - # The name should be `nil` or non-empty string that is not a valid constant name - # (to avoid confusing between permanent and temporary names). + # The name should be `nil` or a non-empty string that is not a valid constant + # path (to avoid confusing between permanent and temporary names). # # The method can be useful to distinguish dynamically generated classes and # modules without assigning them to constants. @@ -1651,7 +1656,7 @@ class Module < Object # # In child # In parent - # prog.rb:23: undefined method `hello' for # (NoMethodError) + # prog.rb:23: undefined method 'hello' for # (NoMethodError) # def undef_method: (*interned arg0) -> self diff --git a/core/numeric.rbs b/core/numeric.rbs index e05561d504..3cc0fd6856 100644 --- a/core/numeric.rbs +++ b/core/numeric.rbs @@ -196,7 +196,7 @@ class Numeric def +: (Numeric) -> Numeric # # Returns `self`. @@ -261,13 +261,15 @@ class Numeric # - # Returns the smallest number that is greater than or equal to `self` with a - # precision of `digits` decimal digits. + # Returns the smallest float or integer that is greater than or equal to `self`, + # as specified by the given `ndigits`, which must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). # - # Numeric implements this by converting `self` to a Float and invoking - # Float#ceil. + # Equivalent to `self.to_f.ceil(ndigits)`. + # + # Related: #floor, Float#ceil. # def ceil: () -> Integer | (Integer digits) -> (Integer | Numeric) @@ -387,8 +389,8 @@ class Numeric # 1.eql?(Rational(1, 1)) # => false # 1.eql?(Complex(1, 0)) # => false # - # Method `eql?` is different from +==+ in that `eql?` requires matching types, - # while +==+ does not. + # Method `eql?` is different from `==` in that `eql?` requires matching types, + # while `==` does not. # def eql?: (untyped) -> bool @@ -414,13 +416,15 @@ class Numeric # - # Returns the largest number that is less than or equal to `self` with a - # precision of `digits` decimal digits. + # Returns the largest float or integer that is less than or equal to `self`, as + # specified by the given `ndigits`, which must be an [integer-convertible + # object](rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects). # - # Numeric implements this by converting `self` to a Float and invoking - # Float#floor. + # Equivalent to `self.to_f.floor(ndigits)`. + # + # Related: #ceil, Float#floor. # def floor: () -> Integer | (Integer digits) -> Numeric @@ -526,17 +530,19 @@ class Numeric # rdoc-file=numeric.c # - nonzero? -> self or nil # --> - # Returns `self` if `self` is not a zero value, `nil` otherwise; uses method - # `zero?` for the evaluation. + # Returns +self+ if +self+ is not a zero value, +nil+ otherwise; + # uses method zero? for the evaluation. # - # The returned `self` allows the method to be chained: + # The returned +self+ allows the method to be chained: # - # a = %w[z Bb bB bb BB a aA Aa AA A] - # a.sort {|a, b| (a.downcase <=> b.downcase).nonzero? || a <=> b } - # # => ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"] + # a = %w[z Bb bB bb BB a aA Aa AA A] + # a.sort {|a, b| (a.downcase <=> b.downcase).nonzero? || a <=> b } + # # => ["A", "a", "AA", "Aa", "aA", "BB", "Bb", "bB", "bb", "z"] # - # Of the Core and Standard Library classes, Integer, Float, Rational, and - # Complex use this implementation. + # Of the Core and Standard Library classes, + # Integer, Float, Rational, and Complex use this implementation. + # + # Related: #zero? # def nonzero?: () -> self? @@ -664,86 +670,83 @@ class Numeric # --> # Generates a sequence of numbers; with a block given, traverses the sequence. # - # Of the Core and Standard Library classes, - # Integer, Float, and Rational use this implementation. - # - # A quick example: - # - # squares = [] - # 1.step(by: 2, to: 10) {|i| squares.push(i*i) } - # squares # => [1, 9, 25, 49, 81] - # - # The generated sequence: - # - # - Begins with +self+. - # - Continues at intervals of +by+ (which may not be zero). - # - Ends with the last number that is within or equal to +to+; - # that is, less than or equal to +to+ if +by+ is positive, - # greater than or equal to +to+ if +by+ is negative. - # If +to+ is +nil+, the sequence is of infinite length. - # - # If a block is given, calls the block with each number in the sequence; - # returns +self+. If no block is given, returns an Enumerator::ArithmeticSequence. - # - # Keyword Arguments - # - # With keyword arguments +by+ and +to+, - # their values (or defaults) determine the step and limit: - # - # # Both keywords given. - # squares = [] - # 4.step(by: 2, to: 10) {|i| squares.push(i*i) } # => 4 - # squares # => [16, 36, 64, 100] - # cubes = [] - # 3.step(by: -1.5, to: -3) {|i| cubes.push(i*i*i) } # => 3 - # cubes # => [27.0, 3.375, 0.0, -3.375, -27.0] - # squares = [] - # 1.2.step(by: 0.2, to: 2.0) {|f| squares.push(f*f) } - # squares # => [1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] - # - # squares = [] - # Rational(6/5).step(by: 0.2, to: 2.0) {|r| squares.push(r*r) } - # squares # => [1.0, 1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] - # - # # Only keyword to given. - # squares = [] - # 4.step(to: 10) {|i| squares.push(i*i) } # => 4 - # squares # => [16, 25, 36, 49, 64, 81, 100] - # # Only by given. - # - # # Only keyword by given - # squares = [] - # 4.step(by:2) {|i| squares.push(i*i); break if i > 10 } - # squares # => [16, 36, 64, 100, 144] - # - # # No block given. - # e = 3.step(by: -1.5, to: -3) # => (3.step(by: -1.5, to: -3)) - # e.class # => Enumerator::ArithmeticSequence - # - # Positional Arguments - # - # With optional positional arguments +to+ and +by+, - # their values (or defaults) determine the step and limit: - # - # squares = [] - # 4.step(10, 2) {|i| squares.push(i*i) } # => 4 - # squares # => [16, 36, 64, 100] - # squares = [] - # 4.step(10) {|i| squares.push(i*i) } - # squares # => [16, 25, 36, 49, 64, 81, 100] - # squares = [] - # 4.step {|i| squares.push(i*i); break if i > 10 } # => nil - # squares # => [16, 25, 36, 49, 64, 81, 100, 121] + # Of the Core and Standard Library classes, Integer, Float, and Rational use + # this implementation. + # + # A quick example: + # + # squares = [] + # 1.step(by: 2, to: 10) {|i| squares.push(i*i) } + # squares # => [1, 9, 25, 49, 81] + # + # The generated sequence: + # + # * Begins with `self`. + # * Continues at intervals of `by` (which may not be zero). + # * Ends with the last number that is within or equal to `to`; that is, less + # than or equal to `to` if `by` is positive, greater than or equal to `to` + # if `by` is negative. If `to` is `nil`, the sequence is of infinite length. + # + # If a block is given, calls the block with each number in the sequence; returns + # `self`. If no block is given, returns an Enumerator::ArithmeticSequence. + # + # **Keyword Arguments** + # + # With keyword arguments `by` and `to`, their values (or defaults) determine the + # step and limit: + # + # # Both keywords given. + # squares = [] + # 4.step(by: 2, to: 10) {|i| squares.push(i*i) } # => 4 + # squares # => [16, 36, 64, 100] + # cubes = [] + # 3.step(by: -1.5, to: -3) {|i| cubes.push(i*i*i) } # => 3 + # cubes # => [27.0, 3.375, 0.0, -3.375, -27.0] + # squares = [] + # 1.2.step(by: 0.2, to: 2.0) {|f| squares.push(f*f) } + # squares # => [1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] + # + # squares = [] + # Rational(6/5).step(by: 0.2, to: 2.0) {|r| squares.push(r*r) } + # squares # => [1.0, 1.44, 1.9599999999999997, 2.5600000000000005, 3.24, 4.0] + # + # # Only keyword to given. + # squares = [] + # 4.step(to: 10) {|i| squares.push(i*i) } # => 4 + # squares # => [16, 25, 36, 49, 64, 81, 100] + # # Only by given. + # + # # Only keyword by given + # squares = [] + # 4.step(by:2) {|i| squares.push(i*i); break if i > 10 } + # squares # => [16, 36, 64, 100, 144] + # + # # No block given. + # e = 3.step(by: -1.5, to: -3) # => (3.step(by: -1.5, to: -3)) + # e.class # => Enumerator::ArithmeticSequence + # + # **Positional Arguments** + # + # With optional positional arguments `to` and `by`, their values (or defaults) + # determine the step and limit: + # + # squares = [] + # 4.step(10, 2) {|i| squares.push(i*i) } # => 4 + # squares # => [16, 36, 64, 100] + # squares = [] + # 4.step(10) {|i| squares.push(i*i) } + # squares # => [16, 25, 36, 49, 64, 81, 100] + # squares = [] + # 4.step {|i| squares.push(i*i); break if i > 10 } # => nil + # squares # => [16, 25, 36, 49, 64, 81, 100, 121] # # **Implementation Notes** # - # If all the arguments are integers, the loop operates using an integer - # counter. + # If all the arguments are integers, the loop operates using an integer counter. # - # If any of the arguments are floating point numbers, all are converted - # to floats, and the loop is executed - # floor(n + n*Float::EPSILON) + 1 times, - # where n = (limit - self)/step. + # If any of the arguments are floating point numbers, all are converted to + # floats, and the loop is executed *floor(n + n*Float::EPSILON) + 1* times, + # where *n = (limit - self)/step*. # def step: (?Numeric limit, ?Numeric step) { (Numeric) -> void } -> self | (?Numeric limit, ?Numeric step) -> Enumerator[Numeric, self] diff --git a/core/object_space.rbs b/core/object_space.rbs index d6167ac0b3..9b6152c2c4 100644 --- a/core/object_space.rbs +++ b/core/object_space.rbs @@ -4,9 +4,9 @@ # an iterator. # # ObjectSpace also provides support for object finalizers, procs that will be -# called when a specific object is about to be destroyed by garbage collection. -# See the documentation for `ObjectSpace.define_finalizer` for important -# information on how to use this method correctly. +# called after a specific object was destroyed by garbage collection. See the +# documentation for `ObjectSpace.define_finalizer` for important information on +# how to use this method correctly. # # a = "A" # b = "B" diff --git a/core/object_space/weak_key_map.rbs b/core/object_space/weak_key_map.rbs index 3f755d52cf..74a826e723 100644 --- a/core/object_space/weak_key_map.rbs +++ b/core/object_space/weak_key_map.rbs @@ -22,13 +22,13 @@ module ObjectSpace # # val = nil # GC.start - # # There is no more references to `val`, yet the pair isn't + # # There are 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 + # # There are no more references to `key`, key and value are # # garbage-collected. # map["name"] #=> nil # @@ -54,7 +54,7 @@ module ObjectSpace # 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 + # attributes always, but the values that aren't needed anymore wouldn't be # sitting in the cache forever. # class WeakKeyMap[Key, Value] diff --git a/core/process.rbs b/core/process.rbs index d9d24b88b0..a58dba2b91 100644 --- a/core/process.rbs +++ b/core/process.rbs @@ -50,14 +50,14 @@ # built-in, or if it contains one or more meta characters. # * `exe_path` otherwise. # -# **Argument `command_line`** +# #### Argument `command_line` # # String argument `command_line` is a command line to be passed to a shell; it # must begin with a shell reserved word, begin with a special built-in, or # contain meta characters: # # system('if true; then echo "Foo"; fi') # => true # Shell reserved word. -# system('echo') # => true # Built-in. +# system('exit') # => true # Built-in. # system('date > /tmp/date.tmp') # => true # Contains meta character. # system('date > /nop/date.tmp') # => false # system('date > /nop/date.tmp', exception: true) # Raises RuntimeError. @@ -73,22 +73,85 @@ # See [Execution Shell](rdoc-ref:Process@Execution+Shell) for details about the # shell. # -# **Argument `exe_path`** +# #### Argument `exe_path` # # Argument `exe_path` is one of the following: # -# * The string path to an executable to be called. -# * A 2-element array containing the path to an executable to be called, and -# the string to be used as the name of the executing process. +# * The string path to an executable file to be called: +# +# Example: +# +# system('/usr/bin/date') # => true # Path to date on Unix-style system. +# system('foo') # => nil # Command execlution failed. +# +# Output: +# +# Thu Aug 31 10:06:48 AM CDT 2023 +# +# A path or command name containing spaces without arguments cannot be +# distinguished from `command_line` above, so you must quote or escape the +# entire command name using a shell in platform dependent manner, or use the +# array form below. +# +# If `exe_path` does not contain any path separator, an executable file is +# searched from directories specified with the `PATH` environment variable. +# What the word "executable" means here is depending on platforms. +# +# Even if the file considered "executable", its content may not be in proper +# executable format. In that case, Ruby tries to run it by using `/bin/sh` +# on a Unix-like system, like system(3) does. +# +# File.write('shell_command', 'echo $SHELL', perm: 0o755) +# system('./shell_command') # prints "/bin/sh" or something. +# +# * A 2-element array containing the path to an executable and the string to +# be used as the name of the executing process: +# +# Example: +# +# pid = spawn(['sleep', 'Hello!'], '1') # 2-element array. +# p `ps -p #{pid} -o command=` +# +# Output: +# +# "Hello! 1\n" +# +# ### Arguments `args` +# +# If `command_line` does not contain shell meta characters except for spaces and +# tabs, or `exe_path` is given, Ruby invokes the executable directly. This form +# does not use the shell: +# +# spawn("doesnt_exist") # Raises Errno::ENOENT +# spawn("doesnt_exist", "\n") # Raises Errno::ENOENT +# +# spawn("doesnt_exist\n") # => false +# # sh: 1: doesnot_exist: not found +# +# The error message is from a shell and would vary depending on your system. +# +# If one or more `args` is given after `exe_path`, each is an argument or option +# to be passed to the executable: # # Example: # -# system('/usr/bin/date') # => true # Path to date on Unix-style system. -# system('foo') # => nil # Command failed. +# system('echo', '<', 'C*', '|', '$SHELL', '>') # => true # # Output: # -# Mon Aug 28 11:43:10 AM CDT 2023 +# < C* | $SHELL > +# +# However, there are exceptions on Windows. See [Execution Shell on +# Windows](rdoc-ref:Process@Execution+Shell+on+Windows). +# +# If you want to invoke a path containing spaces with no arguments without +# shell, you will need to use a 2-element array `exe_path`. +# +# Example: +# +# path = '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome' +# spawn(path) # Raises Errno::ENOENT; No such file or directory - /Applications/Google +# spawn([path] * 2) # # ### Execution Options # @@ -213,23 +276,48 @@ # # ### Execution Shell # -# On a Unix-like system, the shell invoked is `/bin/sh`; otherwise the shell -# invoked is determined by environment variable `ENV['RUBYSHELL']`, if defined, -# or `ENV['COMSPEC']` otherwise. -# -# Except for the `COMSPEC` case, the entire string `command_line` is passed as -# an argument to [shell option +# On a Unix-like system, the shell invoked is `/bin/sh`; the entire string +# `command_line` is passed as an argument to [shell option # -c](https://pubs.opengroup.org/onlinepubs/9699919799.2018edition/utilities/sh. # html). # # The shell performs normal shell expansion on the command line: # -# spawn('echo C*') # => 799139 -# Process.wait # => 799139 +# Example: +# +# system('echo $SHELL: C*') # => true +# +# Output: +# +# /bin/bash: CONTRIBUTING.md COPYING COPYING.ja +# +# #### Execution Shell on Windows +# +# On Windows, the shell invoked is determined by environment variable +# `RUBYSHELL`, if defined, or `COMSPEC` otherwise; the entire string +# `command_line` is passed as an argument to `-c` option for `RUBYSHELL`, as +# well as `/bin/sh`, and [/c +# option](https://learn.microsoft.com/en-us/windows-server/administration/window +# s-commands/cmd) for `COMSPEC`. The shell is invoked automatically in the +# following cases: +# +# * The command is a built-in of `cmd.exe`, such as `echo`. +# * The executable file is a batch file; its name ends with `.bat` or `.cmd`. +# +# Note that the command will still be invoked as `command_line` form even when +# called in `exe_path` form, because `cmd.exe` does not accept a script name +# like `/bin/sh` does but only works with `/c` option. +# +# The standard shell `cmd.exe` performs environment variable expansion but does +# not have globbing functionality: +# +# Example: +# +# system("echo %COMSPEC%: C*")' # => true # # Output: # -# CONTRIBUTING.md COPYING COPYING.ja +# C:\WINDOWS\system32\cmd.exe: C* # # ## What's Here # @@ -1193,7 +1281,7 @@ module Process # logical OR of both: # # * Process::WNOHANG: Does not block if no child process is available. - # * Process:WUNTRACED: May return a stopped child process, even if not yet + # * Process::WUNTRACED: May return a stopped child process, even if not yet # reported. # # Not all flags are available on all platforms. @@ -1217,7 +1305,7 @@ module Process # Process.wait2(pid) # # => [309581, #] # - # Process.waitpid2 is an alias for Process.waitpid. + # Process.waitpid2 is an alias for Process.wait2. # def self.wait2: (?Integer pid, ?Integer flags) -> [ Integer, Process::Status ] @@ -1358,7 +1446,7 @@ module Process # logical OR of both: # # * Process::WNOHANG: Does not block if no child process is available. - # * Process:WUNTRACED: May return a stopped child process, even if not yet + # * Process::WUNTRACED: May return a stopped child process, even if not yet # reported. # # Not all flags are available on all platforms. @@ -1382,7 +1470,7 @@ module Process # Process.wait2(pid) # # => [309581, #] # - # Process.waitpid2 is an alias for Process.waitpid. + # Process.waitpid2 is an alias for Process.wait2. # def self.waitpid2: (?Integer pid, ?Integer flags) -> [ Integer, Process::Status ] diff --git a/core/ractor.rbs b/core/ractor.rbs index 55b40d16a4..3772caa3a4 100644 --- a/core/ractor.rbs +++ b/core/ractor.rbs @@ -607,7 +607,8 @@ class Ractor # rdoc-file=ractor.rb # - [](sym) # --> - # get a value from ractor-local storage + # get a value from ractor-local storage of current Ractor Obsolete and use + # Ractor.[] instead. # def []: (interned sym) -> untyped @@ -615,7 +616,8 @@ class Ractor # rdoc-file=ractor.rb # - []=(sym, val) # --> - # set a value in ractor-local storage + # set a value in ractor-local storage of current Ractor Obsolete and use + # Ractor.[]= instead. # def []=: [T] (interned sym, T val) -> T diff --git a/core/range.rbs b/core/range.rbs index a76f1db1bf..f70f7da55b 100644 --- a/core/range.rbs +++ b/core/range.rbs @@ -13,14 +13,13 @@ # (1...4).to_a # => [1, 2, 3] # ('a'...'d').to_a # => ["a", "b", "c"] # -# A range may be created using method Range.new: +# * Method Range.new: # -# # Ranges that by default include the given end value. -# Range.new(1, 4).to_a # => [1, 2, 3, 4] -# Range.new('a', 'd').to_a # => ["a", "b", "c", "d"] -# # Ranges that use third argument +exclude_end+ to exclude the given end value. -# Range.new(1, 4, true).to_a # => [1, 2, 3] -# Range.new('a', 'd', true).to_a # => ["a", "b", "c"] +# # Ranges that by default include the given end value. Range.new(1, 4).to_a +# # => [1, 2, 3, 4] Range.new('a', 'd').to_a # => ["a", "b", "c", "d"] # +# Ranges that use third argument `exclude_end` to exclude the given end +# value. Range.new(1, 4, true).to_a # => [1, 2, 3] Range.new('a', 'd', +# true).to_a # => ["a", "b", "c"] # # ## Beginless Ranges # @@ -41,8 +40,12 @@ # A beginless range may be used to slice an array: # # a = [1, 2, 3, 4] -# r = (..2) # => nil...2 -# a[r] # => [1, 2] +# # Include the third array element in the slice +# r = (..2) # => nil..2 +# a[r] # => [1, 2, 3] +# # Exclude the third array element from the slice +# r = (...2) # => nil...2 +# a[r] # => [1, 2] # # Method `each` for a beginless range raises an exception. # @@ -95,8 +98,8 @@ # ## Ranges and Other Classes # # An object may be put into a range if its class implements instance method -# `<=>`. Ruby core classes that do so include Array, Complex, File::Stat, Float, -# Integer, Kernel, Module, Numeric, Rational, String, Symbol, and Time. +# `#<=>`. Ruby core classes that do so include Array, Complex, File::Stat, +# Float, Integer, Kernel, Module, Numeric, Rational, String, Symbol, and Time. # # Example: # @@ -125,12 +128,12 @@ # ## Ranges and User-Defined Classes # # A user-defined class that is to be used in a range must implement instance -# `<=>`; see Integer#<=>. To make iteration available, it must also implement -# instance method `succ`; see Integer#succ. +# method `#<=>`; see Integer#<=>. To make iteration available, it must also +# implement instance method `succ`; see Integer#succ. # -# The class below implements both `<=>` and `succ`, and so can be used both to +# The class below implements both `#<=>` and `succ`, and so can be used both to # construct ranges and to iterate over them. Note that the Comparable module is -# included so the `==` method is defined in terms of `<=>`. +# included so the `==` method is defined in terms of `#<=>`. # # # Represent a string of 'X' characters. # class Xs @@ -236,29 +239,24 @@ class Range[out Elem] < Object # - # Iterates over the elements of `self`. + # Same as #step (but doesn't provide default value for `n`). The method is + # convenient for experssive producing of Enumerator::ArithmeticSequence. # - # With a block given, calls the block with selected elements of the range; - # returns `self`: + # array = [0, 1, 2, 3, 4, 5, 6] # - # a = [] - # (1..5).%(2) {|element| a.push(element) } # => 1..5 - # a # => [1, 3, 5] - # a = [] - # ('a'..'e').%(2) {|element| a.push(element) } # => "a".."e" - # a # => ["a", "c", "e"] - # - # With no block given, returns an enumerator, which will be of class - # Enumerator::ArithmeticSequence if `self` is numeric; otherwise of class - # Enumerator: + # # slice each second element: + # seq = (0..) % 2 #=> ((0..).%(2)) + # array[seq] #=> [0, 2, 4, 6] + # # or just + # array[(0..) % 2] #=> [0, 2, 4, 6] # - # e = (1..5) % 2 # => ((1..5).%(2)) - # e.class # => Enumerator::ArithmeticSequence - # ('a'..'e') % 2 # => # + # Note that due to operator precedence in Ruby, parentheses are mandatory around + # range in this case: # - # Related: Range#step. + # (0..7) % 2 #=> ((0..7).%(2)) -- as expected + # 0..7 % 2 #=> 0..1 -- parsed as 0..(7 % 2) # def %: (Numeric | int n) -> Enumerator[Elem, self] | (Numeric | int n) { (Elem element) -> void } -> self @@ -436,7 +434,7 @@ class Range[out Elem] < Object # Returns `false` if either: # # * The begin value of `self` is larger than its end value. - # * An internal call to `<=>` returns `nil`; that is, the operands are not + # * An internal call to `#<=>` returns `nil`; that is, the operands are not # comparable. # # Beginless ranges cover all values of the same type before the end, excluding @@ -670,7 +668,7 @@ class Range[out Elem] < Object # - max {|a, b| ... } -> object # - max(n) {|a, b| ... } -> array # --> - # Returns the maximum value in `self`, using method `<=>` or a given block for + # Returns the maximum value in `self`, using method `#<=>` or a given block for # comparison. # # With no argument and no block given, returns the maximum-valued element of @@ -755,7 +753,7 @@ class Range[out Elem] < Object # - min {|a, b| ... } -> object # - min(n) {|a, b| ... } -> array # --> - # Returns the minimum value in `self`, using method `<=>` or a given block for + # Returns the minimum value in `self`, using method `#<=>` or a given block for # comparison. # # With no argument and no block given, returns the minimum-valued element of @@ -847,7 +845,7 @@ class Range[out Elem] < Object # # (1..3).overlap?(1) # TypeError # - # Returns `false` if an internal call to `<=>` returns `nil`; that is, the + # Returns `false` if an internal call to `#<=>` returns `nil`; that is, the # operands are not comparable. # # (1..3).overlap?('a'..'d') # => false @@ -929,7 +927,12 @@ class Range[out Elem] < Object # (1..4).size # => 4 # (1...4).size # => 3 # (1..).size # => Infinity - # ('a'..'z').size #=> nil + # ('a'..'z').size # => nil + # + # If `self` is not iterable, raises an exception: + # + # (0.5..2.5).size # TypeError + # (..1).size # TypeError # # Related: Range#count. # @@ -938,40 +941,81 @@ class Range[out Elem] < Object # - # Iterates over the elements of `self`. + # Iterates over the elements of range in steps of `s`. The iteration is + # performed by `+` operator: # - # With a block given and no argument, calls the block each element of the range; - # returns `self`: + # (0..6).step(2) { puts _1 } #=> 1..5 + # # Prints: 0, 2, 4, 6 # - # a = [] - # (1..5).step {|element| a.push(element) } # => 1..5 - # a # => [1, 2, 3, 4, 5] - # a = [] - # ('a'..'e').step {|element| a.push(element) } # => "a".."e" - # a # => ["a", "b", "c", "d", "e"] + # # Iterate between two dates in step of 1 day (24 hours) + # (Time.utc(2022, 2, 24)..Time.utc(2022, 3, 1)).step(24*60*60) { puts _1 } + # # Prints: + # # 2022-02-24 00:00:00 UTC + # # 2022-02-25 00:00:00 UTC + # # 2022-02-26 00:00:00 UTC + # # 2022-02-27 00:00:00 UTC + # # 2022-02-28 00:00:00 UTC + # # 2022-03-01 00:00:00 UTC # - # With a block given and a positive integer argument `n` given, calls the block - # with element `0`, element `n`, element `2n`, and so on: + # If ` + step` decreases the value, iteration is still performed when step + # `begin` is higher than the `end`: # - # a = [] - # (1..5).step(2) {|element| a.push(element) } # => 1..5 - # a # => [1, 3, 5] - # a = [] - # ('a'..'e').step(2) {|element| a.push(element) } # => "a".."e" - # a # => ["a", "c", "e"] + # (0..6).step(-2) { puts _1 } + # # Prints nothing + # + # (6..0).step(-2) { puts _1 } + # # Prints: 6, 4, 2, 0 + # + # (Time.utc(2022, 3, 1)..Time.utc(2022, 2, 24)).step(-24*60*60) { puts _1 } + # # Prints: + # # 2022-03-01 00:00:00 UTC + # # 2022-02-28 00:00:00 UTC + # # 2022-02-27 00:00:00 UTC + # # 2022-02-26 00:00:00 UTC + # # 2022-02-25 00:00:00 UTC + # # 2022-02-24 00:00:00 UTC + # + # When the block is not provided, and range boundaries and step are Numeric, the + # method returns Enumerator::ArithmeticSequence. + # + # (1..5).step(2) # => ((1..5).step(2)) + # (1.0..).step(1.5) #=> ((1.0..).step(1.5)) + # (..3r).step(1/3r) #=> ((..3/1).step((1/3))) + # + # Enumerator::ArithmeticSequence can be further used as a value object for + # iteration or slicing of collections (see Array#[]). There is a convenience + # method #% with behavior similar to `step` to produce arithmetic sequences more + # expressively: + # + # # Same as (1..5).step(2) + # (1..5) % 2 # => ((1..5).%(2)) + # + # In a generic case, when the block is not provided, Enumerator is returned: + # + # ('a'..).step('b') #=> # + # ('a'..).step('b').take(3) #=> ["a", "ab", "abb"] + # + # If `s` is not provided, it is considered `1` for ranges with numeric `begin`: + # + # (1..5).step { p _1 } + # # Prints: 1, 2, 3, 4, 5 + # + # For non-Numeric ranges, step absence is an error: # - # With no block given, returns an enumerator, which will be of class - # Enumerator::ArithmeticSequence if `self` is numeric; otherwise of class - # Enumerator: + # (Time.utc(2022, 3, 1)..Time.utc(2022, 2, 24)).step { p _1 } + # # raises: step is required for non-numeric ranges (ArgumentError) # - # e = (1..5).step(2) # => ((1..5).step(2)) - # e.class # => Enumerator::ArithmeticSequence - # ('a'..'e').step # => # + # For backward compatibility reasons, String ranges support the iteration both + # with string step and with integer step. In the latter case, the iteration is + # performed by calculating the next values with String#succ: # - # Related: Range#%. + # ('a'..'e').step(2) { p _1 } + # # Prints: a, c, e + # ('a'..'e').step { p _1 } + # # Default step 1; prints: a, b, c, d, e # def step: (?Numeric | int n) -> Enumerator[Elem, self] | (?Numeric | int n) { (Elem element) -> void } -> self @@ -1004,8 +1048,8 @@ class Range[out Elem] < Object # Returns `true` if and only if: # # * `other` is a range. - # * `other.begin eql? self.begin`. - # * `other.end eql? self.end`. + # * `other.begin.eql?(self.begin)`. + # * `other.end.eql?(self.end)`. # * `other.exclude_end? == self.exclude_end?`. # # Otherwise returns `false`. diff --git a/core/rbs/unnamed/argf.rbs b/core/rbs/unnamed/argf.rbs index 6085438b52..b443954f30 100644 --- a/core/rbs/unnamed/argf.rbs +++ b/core/rbs/unnamed/argf.rbs @@ -1,45 +1,248 @@ module RBS module Unnamed # - # ARGF is a stream designed for use in scripts that process files given as - # command-line arguments or passed in via STDIN. + # ## ARGF and `ARGV` # - # The arguments passed to your script are stored in the `ARGV` Array, one - # argument per element. ARGF assumes that any arguments that aren't filenames - # have been removed from `ARGV`. For example: + # The ARGF object works with the array at global variable `ARGV` to make + # `$stdin` and file streams available in the Ruby program: # - # $ ruby argf.rb --verbose file1 file2 + # * **ARGV** may be thought of as the **argument vector** array. # - # ARGV #=> ["--verbose", "file1", "file2"] - # option = ARGV.shift #=> "--verbose" - # ARGV #=> ["file1", "file2"] + # Initially, it contains the command-line arguments and options that are + # passed to the Ruby program; the program can modify that array as it likes. # - # You can now use ARGF to work with a concatenation of each of these named - # files. For instance, ARGF.read will return the contents of *file1* followed by - # the contents of *file2*. + # * **ARGF** may be thought of as the **argument files** object. # - # After a file in `ARGV` has been read ARGF removes it from the Array. Thus, - # after all files have been read `ARGV` will be empty. + # It can access file streams and/or the `$stdin` stream, based on what it + # finds in `ARGV`. This provides a convenient way for the command line to + # specify streams for a Ruby program to read. # - # You can manipulate `ARGV` yourself to control what ARGF operates on. If you - # remove a file from `ARGV`, it is ignored by ARGF; if you add files to `ARGV`, - # they are treated as if they were named on the command line. For example: + # ## Reading # - # ARGV.replace ["file1"] - # ARGF.readlines # Returns the contents of file1 as an Array - # ARGV #=> [] - # ARGV.replace ["file2", "file3"] - # ARGF.read # Returns the contents of file2 and file3 + # ARGF may read from *source* streams, which at any particular time are + # determined by the content of `ARGV`. # - # If `ARGV` is empty, ARGF acts as if it contained `"-"` that makes ARGF read - # from STDIN, i.e. the data piped or typed to your script. For example: + # ### Simplest Case # - # $ echo "glark" | ruby -e 'p ARGF.read' - # "glark\n" + # When the *very first* ARGF read occurs with an empty `ARGV` (`[]`), the source + # is `$stdin`: # - # $ echo Glark > file1 - # $ echo "glark" | ruby -e 'p ARGF.read' -- - file1 - # "glark\nGlark\n" + # * File `t.rb`: + # + # p ['ARGV', ARGV] + # p ['ARGF.read', ARGF.read] + # + # * Commands and outputs (see below for the content of files `foo.txt` and + # `bar.txt`): + # + # $ echo "Open the pod bay doors, Hal." | ruby t.rb + # ["ARGV", []] + # ["ARGF.read", "Open the pod bay doors, Hal.\n"] + # + # $ cat foo.txt bar.txt | ruby t.rb + # ["ARGV", []] + # ["ARGF.read", "Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"] + # + # ### About the Examples + # + # Many examples here assume the existence of files `foo.txt` and `bar.txt`: + # + # $ cat foo.txt + # Foo 0 + # Foo 1 + # $ cat bar.txt + # Bar 0 + # Bar 1 + # Bar 2 + # Bar 3 + # + # ### Sources in `ARGV` + # + # For any ARGF read *except* the [simplest case](rdoc-ref:ARGF@Simplest+Case) + # (that is, *except* for the *very first* ARGF read with an empty `ARGV`), the + # sources are found in `ARGV`. + # + # ARGF assumes that each element in array `ARGV` is a potential source, and is + # one of: + # + # * The string path to a file that may be opened as a stream. + # * The character `'-'`, meaning stream `$stdin`. + # + # Each element that is *not* one of these should be removed from `ARGV` before + # ARGF accesses that source. + # + # In the following example: + # + # * Filepaths `foo.txt` and `bar.txt` may be retained as potential sources. + # * Options `--xyzzy` and `--mojo` should be removed. + # + # Example: + # + # * File `t.rb`: + # + # # Print arguments (and options, if any) found on command line. + # p ['ARGV', ARGV] + # + # * Command and output: + # + # $ ruby t.rb --xyzzy --mojo foo.txt bar.txt + # ["ARGV", ["--xyzzy", "--mojo", "foo.txt", "bar.txt"]] + # + # ARGF's stream access considers the elements of `ARGV`, left to right: + # + # * File `t.rb`: + # + # p "ARGV: #{ARGV}" + # p "Line: #{ARGF.read}" # Read everything from all specified streams. + # + # * Command and output: + # + # $ ruby t.rb foo.txt bar.txt + # "ARGV: [\"foo.txt\", \"bar.txt\"]" + # "Read: Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n" + # + # Because the value at `ARGV` is an ordinary array, you can manipulate it to + # control which sources ARGF considers: + # + # * If you remove an element from `ARGV`, ARGF will not consider the + # corresponding source. + # * If you add an element to `ARGV`, ARGF will consider the corresponding + # source. + # + # Each element in `ARGV` is removed when its corresponding source is accessed; + # when all sources have been accessed, the array is empty: + # + # * File `t.rb`: + # + # until ARGV.empty? && ARGF.eof? + # p "ARGV: #{ARGV}" + # p "Line: #{ARGF.readline}" # Read each line from each specified stream. + # end + # + # * Command and output: + # + # $ ruby t.rb foo.txt bar.txt + # "ARGV: [\"foo.txt\", \"bar.txt\"]" + # "Line: Foo 0\n" + # "ARGV: [\"bar.txt\"]" + # "Line: Foo 1\n" + # "ARGV: [\"bar.txt\"]" + # "Line: Bar 0\n" + # "ARGV: []" + # "Line: Bar 1\n" + # "ARGV: []" + # "Line: Bar 2\n" + # "ARGV: []" + # "Line: Bar 3\n" + # + # #### Filepaths in `ARGV` + # + # The `ARGV` array may contain filepaths the specify sources for ARGF reading. + # + # This program prints what it reads from files at the paths specified on the + # command line: + # + # * File `t.rb`: + # + # p ['ARGV', ARGV] + # # Read and print all content from the specified sources. + # p ['ARGF.read', ARGF.read] + # + # * Command and output: + # + # $ ruby t.rb foo.txt bar.txt + # ["ARGV", [foo.txt, bar.txt] + # ["ARGF.read", "Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n"] + # + # #### Specifying `$stdin` in `ARGV` + # + # To specify stream `$stdin` in `ARGV`, us the character `'-'`: + # + # * File `t.rb`: + # + # p ['ARGV', ARGV] + # p ['ARGF.read', ARGF.read] + # + # * Command and output: + # + # $ echo "Open the pod bay doors, Hal." | ruby t.rb - + # ["ARGV", ["-"]] + # ["ARGF.read", "Open the pod bay doors, Hal.\n"] + # + # When no character `'-'` is given, stream `$stdin` is ignored (exception: see + # [Specifying $stdin in ARGV](rdoc-ref:ARGF@Specifying+-24stdin+in+ARGV)): + # + # * Command and output: + # + # $ echo "Open the pod bay doors, Hal." | ruby t.rb foo.txt bar.txt + # "ARGV: [\"foo.txt\", \"bar.txt\"]" + # "Read: Foo 0\nFoo 1\nBar 0\nBar 1\nBar 2\nBar 3\n" + # + # #### Mixtures and Repetitions in `ARGV` + # + # For an ARGF reader, `ARGV` may contain any mixture of filepaths and character + # `'-'`, including repetitions. + # + # #### Modifications to `ARGV` + # + # The running Ruby program may make any modifications to the `ARGV` array; the + # current value of `ARGV` affects ARGF reading. + # + # #### Empty `ARGV` + # + # For an empty `ARGV`, an ARGF read method either returns `nil` or raises an + # exception, depending on the specific method. + # + # ### More Read Methods + # + # As seen above, method ARGF#read reads the content of all sources into a single + # string. Other ARGF methods provide other ways to access that content; these + # include: + # + # * Byte access: #each_byte, #getbyte, #readbyte. + # * Character access: #each_char, #getc, #readchar. + # * Codepoint access: #each_codepoint. + # * Line access: #each_line, #gets, #readline, #readlines. + # * Source access: #read, #read_nonblock, #readpartial. + # + # ### About Enumerable + # + # ARGF includes module Enumerable. Virtually all methods in Enumerable call + # method `#each` in the including class. + # + # **Note well**: In ARGF, method #each returns data from the *sources*, *not* + # from `ARGV`; therefore, for example, `ARGF#entries` returns an array of lines + # from the sources, not an array of the strings from `ARGV`: + # + # * File `t.rb`: + # + # p ['ARGV', ARGV] + # p ['ARGF.entries', ARGF.entries] + # + # * Command and output: + # + # $ ruby t.rb foo.txt bar.txt + # ["ARGV", ["foo.txt", "bar.txt"]] + # ["ARGF.entries", ["Foo 0\n", "Foo 1\n", "Bar 0\n", "Bar 1\n", "Bar 2\n", "Bar 3\n"]] + # + # ## Writing + # + # If *inplace mode* is in effect, ARGF may write to target streams, which at any + # particular time are determined by the content of ARGV. + # + # Methods about inplace mode: + # + # * #inplace_mode + # * #inplace_mode= + # * #to_write_io + # + # Methods for writing: + # + # * #print + # * #printf + # * #putc + # * #puts + # * #write # %a{annotate:rdoc:copy:ARGF} class ARGFClass @@ -1007,9 +1210,9 @@ module RBS # - # Writes *string* if inplace mode. + # Writes each of the given `objects` if inplace mode. # %a{annotate:rdoc:copy:ARGF#write} def write: (_ToS string) -> Integer diff --git a/core/rbs/unnamed/env_class.rbs b/core/rbs/unnamed/env_class.rbs index 1f6c899c14..5f69ac49bf 100644 --- a/core/rbs/unnamed/env_class.rbs +++ b/core/rbs/unnamed/env_class.rbs @@ -1,17 +1,17 @@ module RBS module Unnamed # - # ENV is a hash-like accessor for environment variables. + # `ENV` is a hash-like accessor for environment variables. # # ### Interaction with the Operating System # - # The ENV object interacts with the operating system's environment variables: + # The `ENV` object interacts with the operating system's environment variables: # - # * When you get the value for a name in ENV, the value is retrieved from + # * When you get the value for a name in `ENV`, the value is retrieved from # among the current environment variables. - # * When you create or set a name-value pair in ENV, the name and value are + # * When you create or set a name-value pair in `ENV`, the name and value are # immediately set in the environment variables. - # * When you delete a name-value pair in ENV, it is immediately deleted from + # * When you delete a name-value pair in `ENV`, it is immediately deleted from # the environment variables. # # ### Names and Values @@ -64,33 +64,34 @@ module RBS # # ### About Ordering # - # ENV enumerates its name/value pairs in the order found in the operating - # system's environment variables. Therefore the ordering of ENV content is + # `ENV` enumerates its name/value pairs in the order found in the operating + # system's environment variables. Therefore the ordering of `ENV` content is # OS-dependent, and may be indeterminate. # # This will be seen in: - # * A Hash returned by an ENV method. - # * An Enumerator returned by an ENV method. + # * A Hash returned by an `ENV` method. + # * An Enumerator returned by an `ENV` method. # * An Array returned by ENV.keys, ENV.values, or ENV.to_a. # * The String returned by ENV.inspect. # * The Array returned by ENV.shift. # * The name returned by ENV.key. # # ### About the Examples - # Some methods in ENV return ENV itself. Typically, there are many environment - # variables. It's not useful to display a large ENV in the examples here, so - # most example snippets begin by resetting the contents of ENV: - # * ENV.replace replaces ENV with a new collection of entries. - # * ENV.clear empties ENV. + # Some methods in `ENV` return `ENV` itself. Typically, there are many + # environment variables. It's not useful to display a large `ENV` in the + # examples here, so most example snippets begin by resetting the contents of + # `ENV`: + # * ENV.replace replaces `ENV` with a new collection of entries. + # * ENV.clear empties `ENV`. # - # ## What's Here + # ### What's Here # - # First, what's elsewhere. Class ENV: + # First, what's elsewhere. Class `ENV`: # # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). # * Extends [module Enumerable](rdoc-ref:Enumerable@What-27s+Here), # - # Here, class ENV provides methods that are useful for: + # Here, class `ENV` provides methods that are useful for: # # * [Querying](rdoc-ref:ENV@Methods+for+Querying) # * [Assigning](rdoc-ref:ENV@Methods+for+Assigning) @@ -99,28 +100,28 @@ module RBS # * [Converting](rdoc-ref:ENV@Methods+for+Converting) # * [And more ....](rdoc-ref:ENV@More+Methods) # - # ### Methods for Querying + # #### Methods for Querying # # * ::[]: Returns the value for the given environment variable name if it # exists: - # * ::empty?: Returns whether ENV is empty. - # * ::has_value?, ::value?: Returns whether the given value is in ENV. + # * ::empty?: Returns whether `ENV` is empty. + # * ::has_value?, ::value?: Returns whether the given value is in `ENV`. # * ::include?, ::has_key?, ::key?, ::member?: Returns whether the given name - # is in ENV. + # is in `ENV`. # * ::key: Returns the name of the first entry with the given value. # * ::size, ::length: Returns the number of entries. # * ::value?: Returns whether any entry has the given value. # - # ### Methods for Assigning + # #### Methods for Assigning # # * ::[]=, ::store: Creates, updates, or deletes the named environment # variable. - # * ::clear: Removes every environment variable; returns ENV: - # * ::update, ::merge!: Adds to ENV each key/value pair in the given hash. - # * ::replace: Replaces the entire content of the ENV with the name/value + # * ::clear: Removes every environment variable; returns `ENV`: + # * ::update, ::merge!: Adds to `ENV` each key/value pair in the given hash. + # * ::replace: Replaces the entire content of the `ENV` with the name/value # pairs in the given hash. # - # ### Methods for Deleting + # #### Methods for Deleting # # * ::delete: Deletes the named environment variable name if it exists. # * ::delete_if: Deletes entries selected by the block. @@ -129,22 +130,22 @@ module RBS # * ::select!, ::filter!: Deletes entries selected by the block. # * ::shift: Removes and returns the first entry. # - # ### Methods for Iterating + # #### Methods for Iterating # # * ::each, ::each_pair: Calls the block with each name/value pair. # * ::each_key: Calls the block with each name. # * ::each_value: Calls the block with each value. # - # ### Methods for Converting + # #### Methods for Converting # # * ::assoc: Returns a 2-element array containing the name and value of the # named environment variable if it exists: - # * ::clone: Returns ENV (and issues a warning). + # * ::clone: Returns `ENV` (and issues a warning). # * ::except: Returns a hash of all name/value pairs except those given. # * ::fetch: Returns the value for the given name. - # * ::inspect: Returns the contents of ENV as a string. - # * ::invert: Returns a hash whose keys are the ENV values, and whose values - # are the corresponding ENV names. + # * ::inspect: Returns the contents of `ENV` as a string. + # * ::invert: Returns a hash whose keys are the `ENV` values, and whose values + # are the corresponding `ENV` names. # * ::keys: Returns an array of all names. # * ::rassoc: Returns the name and value of the first found entry that has the # given value. @@ -159,11 +160,11 @@ module RBS # * ::values: Returns all values as an array. # * ::values_at: Returns an array of the values for the given name. # - # ### More Methods + # #### More Methods # # * ::dup: Raises an exception. # * ::freeze: Raises an exception. - # * ::rehash: Returns `nil`, without modifying ENV. + # * ::rehash: Returns `nil`, without modifying `ENV`. # %a{annotate:rdoc:copy:ENV} class ENVClass diff --git a/core/rbs/unnamed/random.rbs b/core/rbs/unnamed/random.rbs index c295ccafb1..ec4dd7aab5 100644 --- a/core/rbs/unnamed/random.rbs +++ b/core/rbs/unnamed/random.rbs @@ -284,8 +284,7 @@ module RBS # # The result contains 122 random bits (15.25 random bytes). # - # See [RFC4122](https://datatracker.ietf.org/doc/html/rfc4122) for details of - # UUID. + # See [RFC9562](https://www.rfc-editor.org/rfc/rfc9562) for details of UUIDv4. # %a{annotate:rdoc:copy:Random::Formatter#uuid} def uuid: () -> String diff --git a/core/regexp.rbs b/core/regexp.rbs index d4223cafbe..108942a9e5 100644 --- a/core/regexp.rbs +++ b/core/regexp.rbs @@ -210,8 +210,9 @@ # # ### Source Literals # -# The source literal largely behaves like a double-quoted string; see [String -# Literals](rdoc-ref:syntax/literals.rdoc@String+Literals). +# The source literal largely behaves like a double-quoted string; see +# [Double-Quoted String +# Literals](rdoc-ref:syntax/literals.rdoc@Double-Quoted+String+Literals). # # In particular, a source literal may contain interpolated expressions: # @@ -1352,7 +1353,7 @@ class Regexp # - Regexp.last_match(n) -> string or nil # - Regexp.last_match(name) -> string or nil # --> - # With no argument, returns the value of `$!`, which is the result of the most + # With no argument, returns the value of `$~`, which is the result of the most # recent pattern match (see [Regexp global # variables](rdoc-ref:Regexp@Global+Variables)): # diff --git a/core/ruby_vm.rbs b/core/ruby_vm.rbs index 6f3d7a62c8..a47a2e16be 100644 --- a/core/ruby_vm.rbs +++ b/core/ruby_vm.rbs @@ -386,9 +386,8 @@ end # access children nodes by name, etc. # # If you are looking for a stable API or an API working under multiple Ruby -# implementations, consider using the *parser* gem or Ripper. If you would like -# to make RubyVM::AbstractSyntaxTree stable, please join the discussion at -# https://bugs.ruby-lang.org/issues/14844. +# implementations, consider using the *prism* gem, which is the official Ruby +# API to parse Ruby code. # module RubyVM::AbstractSyntaxTree # # Enable YJIT compilation. `stats` option decides whether to enable YJIT stats - # or not. - # * `false`: Disable stats. - # * `true`: Enable stats. Print stats at exit. - # * `:quiet`: Enable stats. Do not print stats at exit. + # or not. `compilation_log` decides + # whether to enable YJIT compilation logging or not. + # `stats`: + # * `false`: Don't enable stats. + # * `true`: Enable stats. Print stats at exit. + # * `:quiet`: Enable stats. Do not print stats at exit. + # `log`: + # * `false`: Don't enable the log. + # * `true`: Enable the log. Print log at exit. + # * `:quiet`: Enable the log. Do not print log at exit. # def self.enable: (?stats: false | true | :quiet) -> void @@ -671,11 +676,13 @@ module RubyVM::YJIT # # Return a hash for statistics generated for the `--yjit-stats` command line # option. # Return `nil` when option is not passed or unavailable. + # If a symbol argument is provided, return only the value for the named stat. + # If any other type is provided, raises TypeError. # def self.runtime_stats: (?context: bool) -> Hash[untyped, untyped]? diff --git a/core/rubygems/platform.rbs b/core/rubygems/platform.rbs index 7f8f5dedc7..a434fe474c 100644 --- a/core/rubygems/platform.rbs +++ b/core/rubygems/platform.rbs @@ -1,12 +1,3 @@ -# -# TruffleRuby >= 24 defines REUSE_AS_BINARY_ON_TRUFFLERUBY in -# defaults/truffleruby. However, TruffleRuby < 24 defines -# REUSE_AS_BINARY_ON_TRUFFLERUBY directly in its copy of -# lib/rubygems/platform.rb, so it is not defined if RubyGems is updated (gem -# update --system). Instead, we define it here in that case, similar to -# bundler/lib/bundler/rubygems_ext.rb. We must define it here and not in -# platform.rb because platform.rb is loaded before defaults/truffleruby. -# # # Available list of platforms for targeting Gem installations. # diff --git a/core/set.rbs b/core/set.rbs index 78a1860652..87af3ce5cd 100644 --- a/core/set.rbs +++ b/core/set.rbs @@ -388,7 +388,7 @@ class Set[unchecked out A] # # Deletes every element of the set for which block evaluates to # true, and returns self. Returns an enumerator if no block is @@ -492,7 +492,7 @@ class Set[unchecked out A] # # Deletes every element of the set for which block evaluates to # false, and returns self. Returns an enumerator if no block is @@ -600,7 +600,7 @@ class Set[unchecked out A] # rdoc-file=lib/set.rb # - to_a() # --> - # Converts the set to an array. The order of elements is uncertain. + # Returns an array containing all elements in the set. # Set[1, 2].to_a #=> [1, 2] # Set[1, 'c', :s].to_a #=> [1, "c", :s] # diff --git a/core/string.rbs b/core/string.rbs index 1374cc2c37..0f2d594e36 100644 --- a/core/string.rbs +++ b/core/string.rbs @@ -1,12 +1,12 @@ # -# A String object has an arbitrary sequence of bytes, typically representing -# text or binary data. A String object may be created using String::new or as +# A `String` object has an arbitrary sequence of bytes, typically representing +# text or binary data. A `String` object may be created using String::new or as # literals. # # String objects differ from Symbol objects in that Symbol objects are designed # to be used as identifiers, instead of text or data. # -# You can create a String object explicitly with: +# You can create a `String` object explicitly with: # # * A [string literal](rdoc-ref:syntax/literals.rdoc@String+Literals). # * A [heredoc literal](rdoc-ref:syntax/literals.rdoc@Here+Document+Literals). @@ -15,7 +15,7 @@ # # * Method #String. # -# Some String methods modify `self`. Typically, a method whose name ends with +# Some `String` methods modify `self`. Typically, a method whose name ends with # `!` modifies `self` and returns `self`; often a similarly named method # (without the `!`) returns a new string. # @@ -28,9 +28,11 @@ # These methods perform substitutions: # # * String#sub: One substitution (or none); returns a new string. -# * String#sub!: One substitution (or none); returns `self`. +# * String#sub!: One substitution (or none); returns `self` if any changes, +# `nil` otherwise. # * String#gsub: Zero or more substitutions; returns a new string. -# * String#gsub!: Zero or more substitutions; returns `self`. +# * String#gsub!: Zero or more substitutions; returns `self` if any changes, +# `nil` otherwise. # # Each of these methods takes: # @@ -63,14 +65,14 @@ # # 'THX1138'.gsub('\d+', '00') # => "THX1138" # -# **\String `replacement`** +# **`String` `replacement`** # # If `replacement` is a string, that string will determine the replacing string # that is to be substituted for the matched text. # # Each of the examples above uses a simple string as the replacing string. # -# String `replacement` may contain back-references to the pattern's captures: +# `String` `replacement` may contain back-references to the pattern's captures: # # * `\n` (*n* a non-negative integer) refers to `$n`. # * `\k` refers to the named capture `name`. @@ -133,7 +135,7 @@ # # ## Whitespace in Strings # -# In class String, *whitespace* is defined as a contiguous sequence of +# In class `String`, *whitespace* is defined as a contiguous sequence of # characters consisting of any mixture of the following: # # * NL (null): `"\x00"`, `"\u0000"`. @@ -150,16 +152,15 @@ # * #rstrip, #rstrip!: strip trailing whitespace. # * #strip, #strip!: strip leading and trailing whitespace. # -# ## String Slices +# ## `String` Slices # # A *slice* of a string is a substring that is selected by certain criteria. # # These instance methods make use of slicing: # -# * String#[] (also aliased as String#slice) returns a slice copied from -# `self`. -# * String#[]= returns a copy of `self` with a slice replaced. -# * String#slice! returns `self` with a slice removed. +# * String#[] (aliased as String#slice): returns a slice copied from `self`. +# * String#[]=: returns a copy of `self` with a slice replaced. +# * String#slice!: returns `self` with a slice removed. # # Each of the above methods takes arguments that determine the slice to be # copied or replaced. @@ -280,7 +281,7 @@ # # **`string[substring]`** # -# When the single String argument `substring` is given, returns the substring +# When the single `String` argument `substring` is given, returns the substring # from `self` if found, otherwise `nil`: # # 'foo'['oo'] # => "oo" @@ -288,12 +289,12 @@ # # ## What's Here # -# First, what's elsewhere. Class String: +# First, what's elsewhere. Class `String`: # # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). # * Includes [module Comparable](rdoc-ref:Comparable@What-27s+Here). # -# Here, class String provides methods that are useful for: +# Here, class `String` provides methods that are useful for: # # * [Creating a String](rdoc-ref:String@Methods+for+Creating+a+String) # * [Frozen/Unfrozen @@ -304,10 +305,10 @@ # * [Converting to New # String](rdoc-ref:String@Methods+for+Converting+to+New+String) # * [Converting to -# Non-String](rdoc-ref:String@Methods+for+Converting+to+Non--5CString) +# Non-String](rdoc-ref:String@Methods+for+Converting+to+Non-String) # * [Iterating](rdoc-ref:String@Methods+for+Iterating) # -# ### Methods for Creating a String +# ### Methods for Creating a `String` # # * ::new: Returns a new string. # * ::try_convert: Returns a new string created from a given object. @@ -316,15 +317,15 @@ # # * #+@: Returns a string that is not frozen: `self`, if not frozen; # `self.dup` otherwise. -# * #-@: Returns a string that is frozen: `self`, if already frozen; -# `self.freeze` otherwise. +# * #-@ (aliased as #dedup): Returns a string that is frozen: `self`, if +# already frozen; `self.freeze` otherwise. # * #freeze: Freezes `self`, if not already frozen; returns `self`. # # ### Methods for Querying # # *Counts* # -# * #length, #size: Returns the count of characters (not bytes). +# * #length (aliased as #size): Returns the count of characters (not bytes). # * #empty?: Returns `true` if `self.length` is zero; `false` otherwise. # * #bytesize: Returns the count of bytes. # * #count: Returns the count of substrings matching given strings. @@ -366,8 +367,8 @@ # # ### Methods for Comparing # -# * #==, #===: Returns `true` if a given other string has the same content as -# `self`. +# * #== (aliased as #===): Returns `true` if a given other string has the same +# content as `self`. # * #eql?: Returns `true` if the content is the same as the given other # string. # * #<=>: Returns -1, 0, or 1 as a given other string is smaller than, equal @@ -377,7 +378,7 @@ # * #casecmp?: Returns `true` if the string is equal to a given string after # Unicode case folding; `false` otherwise. # -# ### Methods for Modifying a String +# ### Methods for Modifying a `String` # # Each of these methods modifies `self`. # @@ -385,6 +386,8 @@ # # * #insert: Returns `self` with a given string inserted at a given offset. # * #<<: Returns `self` concatenated with a given string or integer. +# * #append_as_bytes: Returns `self` concatenated with strings without +# performing any encoding validation or conversion. # # *Substitution* # @@ -392,9 +395,10 @@ # given replacement string; returns `self` if any changes, `nil` otherwise. # * #gsub!: Replaces each substring that matches a given pattern with a given # replacement string; returns `self` if any changes, `nil` otherwise. -# * #succ!, #next!: Returns `self` modified to become its own successor. -# * #replace: Returns `self` with its entire content replaced by a given -# string. +# * #succ! (aliased as #next!): Returns `self` modified to become its own +# successor. +# * #initialize_copy (aliased as #replace): Returns `self` with its entire +# content replaced by a given string. # * #reverse!: Returns `self` with its characters in reverse order. # * #setbyte: Sets the byte at a given integer offset to a given value; # returns the argument. @@ -443,9 +447,9 @@ # * #chop!: Removes trailing newline characters if found; otherwise removes # the last character; returns `self` if any changes, `nil` otherwise. # -# ### Methods for Converting to New String +# ### Methods for Converting to New `String` # -# Each of these methods returns a new String based on `self`, often just a +# Each of these methods returns a new `String` based on `self`, often just a # modified copy of `self`. # # *Extension* @@ -480,7 +484,8 @@ # pattern replaced with a given replacement string;. # * #gsub: Returns a copy of `self` with each substring that matches a given # pattern replaced with a given replacement string. -# * #succ, #next: Returns the string that is the successor to `self`. +# * #succ (aliased as #next): Returns the string that is the successor to +# `self`. # * #reverse: Returns a copy of `self` with its characters in reverse order. # * #tr: Returns a copy of `self` with specified characters replaced with # specified replacement characters. @@ -514,7 +519,7 @@ # last character removed. # * #squeeze: Returns a copy of `self` with contiguous duplicate characters # removed. -# * #[], #slice: Returns a substring determined by a given index, +# * #[] (aliased as #slice): Returns a substring determined by a given index, # start/length, or range, or string. # * #byteslice: Returns a substring determined by a given index, start/length, # or range. @@ -522,12 +527,12 @@ # # *Duplication* # -# * #to_s, $to_str: If `self` is a subclass of String, returns `self` copied -# into a String; otherwise, returns `self`. +# * #to_s (aliased as #to_str): If `self` is a subclass of `String`, returns +# `self` copied into a `String`; otherwise, returns `self`. # -# ### Methods for Converting to Non-String +# ### Methods for Converting to Non-`String` # -# Each of these methods converts the contents of `self` to a non-String. +# Each of these methods converts the contents of `self` to a non-`String`. # # *Characters, Bytes, and Clusters* # @@ -574,7 +579,7 @@ # # * #inspect: Returns copy of `self`, enclosed in double-quotes, with special # characters escaped. -# * #to_sym, #intern: Returns the symbol corresponding to `self`. +# * #intern (aliased as #to_sym): Returns the symbol corresponding to `self`. # # ### Methods for Iterating # @@ -600,14 +605,14 @@ class String # rdoc-file=string.c # - String.try_convert(object) -> object, new_string, or nil # --> - # If `object` is a String object, returns `object`. + # If `object` is a `String` object, returns `object`. # # Otherwise if `object` responds to `:to_str`, calls `object.to_str` and returns # the result. # # Returns `nil` if `object` does not respond to `:to_str`. # - # Raises an exception unless `object.to_str` returns a String object. + # Raises an exception unless `object.to_str` returns a `String` object. # def self.try_convert: (String object) -> String # technically will return `object` unchanged. | (_ToStr object) -> String @@ -708,7 +713,7 @@ class String # rdoc-file=string.c # - string * integer -> new_string # --> - # Returns a new String containing `integer` copies of `self`: + # Returns a new `String` containing `integer` copies of `self`: # # "Ho! " * 3 # => "Ho! Ho! Ho! " # "Ho! " * 0 # => "" @@ -719,7 +724,7 @@ class String # rdoc-file=string.c # - string + other_string -> new_string # --> - # Returns a new String containing `other_string` concatenated to `self`: + # Returns a new `String` containing `other_string` concatenated to `self`: # # "Hello from " + self.to_s # => "Hello from main" # @@ -742,7 +747,7 @@ class String # --> # Returns a frozen, possibly pre-existing copy of the string. # - # The returned String will be deduplicated as long as it does not have any + # The returned `String` will be deduplicated as long as it does not have any # instance variables set on it and is not a String subclass. # # Note that `-string` variant is more convenient for defining constants: @@ -772,6 +777,22 @@ class String # s = 'foo' # s << 33 # => "foo!" # + # If that codepoint is not representable in the encoding of *string*, RangeError + # is raised. + # + # s = 'foo' + # s.encoding # => + # s << 0x00110000 # 1114112 out of char range (RangeError) + # s = 'foo'.encode('EUC-JP') + # s << 0x00800080 # invalid codepoint 0x800080 in EUC-JP (RangeError) + # + # If the encoding is US-ASCII and the codepoint is 0..0xff, *string* is + # automatically promoted to ASCII-8BIT. + # + # s = 'foo'.encode('US-ASCII') + # s << 0xff + # s.encoding # => # + # # Related: String#concat, which takes multiple arguments. # def <<: (string | Integer str_or_codepoint) -> self @@ -815,7 +836,7 @@ class String # Returns `false` if the two strings' encodings are not compatible: # "\u{e4 f6 fc}".encode("ISO-8859-1") == ("\u{c4 d6 dc}") # => false # - # If `object` is not an instance of String but responds to `to_str`, then the + # If `object` is not an instance of `String` but responds to `to_str`, then the # two strings are compared using `object.==`. # def ==: (untyped other) -> bool @@ -832,7 +853,7 @@ class String # Returns `false` if the two strings' encodings are not compatible: # "\u{e4 f6 fc}".encode("ISO-8859-1") == ("\u{c4 d6 dc}") # => false # - # If `object` is not an instance of String but responds to `to_str`, then the + # If `object` is not an instance of `String` but responds to `to_str`, then the # two strings are compared using `object.==`. # alias === == @@ -1030,13 +1051,12 @@ class String # $~ #=> # # # Integer argument `offset`, if given and non-negative, specifies the maximum - # starting byte-based position in the - # string to _end_ the search: + # starting byte-based position in the string to *end* the search: # - # 'foo'.byterindex('o', 0) # => nil - # 'foo'.byterindex('o', 1) # => 1 - # 'foo'.byterindex('o', 2) # => 2 - # 'foo'.byterindex('o', 3) # => 2 + # 'foo'.byterindex('o', 0) # => nil + # 'foo'.byterindex('o', 1) # => 1 + # 'foo'.byterindex('o', 2) # => 2 + # 'foo'.byterindex('o', 3) # => 2 # # If `offset` is a negative Integer, the maximum starting position in the string # to *end* the search is the sum of the string's length and `offset`: @@ -1506,7 +1526,7 @@ class String # # Returns a frozen, possibly pre-existing copy of the string. # - # The returned String will be deduplicated as long as it does not have any + # The returned `String` will be deduplicated as long as it does not have any # instance variables set on it and is not a String subclass. # # Note that `-string` variant is more convenient for defining constants: @@ -2094,7 +2114,7 @@ class String # # Returns `true` if `self` contains `other_string`, `false` otherwise: # @@ -2186,7 +2206,7 @@ class String # - str.intern -> symbol # - str.to_sym -> symbol # --> - # Returns the Symbol corresponding to *str*, creating the symbol if it did not + # Returns the `Symbol` corresponding to *str*, creating the symbol if it did not # previously exist. See Symbol#id2name. # # "Koala".intern #=> :Koala @@ -2392,7 +2412,7 @@ class String # s = '99zz99zz' # s.succ # => "100aa00aa" # - # The successor to an empty String is a new empty String: + # The successor to an empty `String` is a new empty `String`: # # ''.succ # => "" # @@ -2547,13 +2567,12 @@ class String # $~ #=> # # # Integer argument `offset`, if given and non-negative, specifies the maximum - # starting position in the - # string to _end_ the search: + # starting position in the string to *end* the search: # - # 'foo'.rindex('o', 0) # => nil - # 'foo'.rindex('o', 1) # => 1 - # 'foo'.rindex('o', 2) # => 2 - # 'foo'.rindex('o', 3) # => 2 + # 'foo'.rindex('o', 0) # => nil + # 'foo'.rindex('o', 1) # => 1 + # 'foo'.rindex('o', 2) # => 2 + # 'foo'.rindex('o', 3) # => 2 # # If `offset` is a negative Integer, the maximum starting position in the string # to *end* the search is the sum of the string's length and `offset`: @@ -2798,8 +2817,8 @@ class String # # Returns an array of substrings of `self` that are the result of splitting # `self` at each occurrence of the given field separator `field_sep`. @@ -2809,18 +2828,18 @@ class String # * If `$;` is `nil` (its default value), the split occurs just as if # `field_sep` were given as a space character (see below). # - # * If `$;` is a string, the split ocurs just as if `field_sep` were given as + # * If `$;` is a string, the split occurs just as if `field_sep` were given as # that string (see below). # - # When `field_sep` is `' '` and `limit` is `nil`, the split occurs at each - # sequence of whitespace: + # When `field_sep` is `' '` and `limit` is `0` (its default value), the split + # occurs at each sequence of whitespace: # # 'abc def ghi'.split(' ') => ["abc", "def", "ghi"] # "abc \n\tdef\t\n ghi".split(' ') # => ["abc", "def", "ghi"] # 'abc def ghi'.split(' ') => ["abc", "def", "ghi"] # ''.split(' ') => [] # - # When `field_sep` is a string different from `' '` and `limit` is `nil`, the + # When `field_sep` is a string different from `' '` and `limit` is `0`, the # split occurs at each occurrence of `field_sep`; trailing empty substrings are # not returned: # @@ -2832,7 +2851,7 @@ class String # 'тест'.split('т') => ["", "ес"] # 'こんにちは'.split('に') => ["こん", "ちは"] # - # When `field_sep` is a Regexp and `limit` is `nil`, the split occurs at each + # When `field_sep` is a Regexp and `limit` is `0`, the split occurs at each # occurrence of a match; trailing empty substrings are not returned: # # 'abracadabra'.split(/ab/) # => ["", "racad", "ra"] @@ -2845,11 +2864,9 @@ class String # # '1:2:3'.split(/(:)()()/, 2) # => ["1", ":", "", "", "2:3"] # - # As seen above, if `limit` is `nil`, trailing empty substrings are not - # returned; the same is true if `limit` is zero: + # As seen above, if `limit` is `0`, trailing empty substrings are not returned: # # 'aaabcdaaa'.split('a') => ["", "", "", "bcd"] - # 'aaabcdaaa'.split('a', 0) # => ["", "", "", "bcd"] # # If `limit` is positive integer `n`, no more than `n - 1-` splits occur, so # that at most `n` substrings are returned, and trailing empty substrings are @@ -2864,7 +2881,7 @@ class String # Note that if `field_sep` is a Regexp containing groups, their matches are in # the returned array, but do not count toward the limit. # - # If `limit` is negative, it behaves the same as if `limit` was `nil`, meaning + # If `limit` is negative, it behaves the same as if `limit` was zero, meaning # that there is no limit, and trailing empty substrings are included: # # 'aaabcdaaa'.split('a', -1) # => ["", "", "", "bcd", "", "", ""] @@ -2983,8 +3000,8 @@ class String # - sub!(pattern, replacement) -> self or nil # - sub!(pattern) {|match| ... } -> self or nil # --> - # Returns `self` with only the first occurrence (not all occurrences) of the - # given `pattern` replaced. + # Replaces the first occurrence (not all occurrences) of the given `pattern` on + # `self`; returns `self` if a replacement occurred, `nil` otherwise. # # See [Substitution Methods](rdoc-ref:String@Substitution+Methods). # @@ -3044,7 +3061,7 @@ class String # s = '99zz99zz' # s.succ # => "100aa00aa" # - # The successor to an empty String is a new empty String: + # The successor to an empty `String` is a new empty `String`: # # ''.succ # => "" # @@ -3230,19 +3247,19 @@ class String # rdoc-file=string.c # - to_s -> self or string # --> - # Returns `self` if `self` is a String, or `self` converted to a String if - # `self` is a subclass of String. + # Returns `self` if `self` is a `String`, or `self` converted to a `String` if + # `self` is a subclass of `String`. # def to_s: () -> String # - # Returns `self` if `self` is a String, or `self` converted to a String if - # `self` is a subclass of String. + # Returns `self` if `self` is a `String`, or `self` converted to a `String` if + # `self` is a subclass of `String`. # alias to_str to_s # - # Returns the Symbol corresponding to *str*, creating the symbol if it did not + # Returns the `Symbol` corresponding to *str*, creating the symbol if it did not # previously exist. See Symbol#id2name. # # "Koala".intern #=> :Koala @@ -3419,10 +3436,14 @@ class String # - # Extracts data from `self`, forming objects that become the elements of a new - # array; returns that array. See [Packed Data](rdoc-ref:packed_data.rdoc). + # Extracts data from `self`. + # + # If `block` is not given, forming objects that become the elements of a new + # array, and returns that array. Otherwise, yields each object. + # + # See [Packed Data](rdoc-ref:packed_data.rdoc). # def unpack: (string template, ?offset: int) -> Array[Integer | Float | String | nil] | (string template, ?offset: int) { (Integer | Float | String | nil value) -> void } -> nil @@ -3482,7 +3503,7 @@ class String # - upto(other_string, exclusive = false) {|string| ... } -> self # - upto(other_string, exclusive = false) -> new_enumerator # --> - # With a block given, calls the block with each String value returned by + # With a block given, calls the block with each `String` value returned by # successive calls to String#succ; the first value is `self`, the next is # `self.succ`, and so on; the sequence terminates when value `other_string` is # reached; returns `self`: diff --git a/core/struct.rbs b/core/struct.rbs index 5976254905..1026b1c6e9 100644 --- a/core/struct.rbs +++ b/core/struct.rbs @@ -67,7 +67,7 @@ # ### Methods for Querying # # * #hash: Returns the integer hash code. -# * #length, #size: Returns the number of members. +# * #size (aliased as #length): Returns the number of members. # # ### Methods for Comparing # @@ -79,15 +79,15 @@ # ### Methods for Fetching # # * #[]: Returns the value associated with a given member name. -# * #to_a, #values, #deconstruct: Returns the member values in `self` as an -# array. +# * #to_a (aliased as #values, #deconstruct): Returns the member values in +# `self` as an array. # * #deconstruct_keys: Returns a hash of the name/value pairs for given member # names. # * #dig: Returns the object in nested objects that is specified by a given # member name and additional arguments. # * #members: Returns an array of the member names. -# * #select, #filter: Returns an array of member values from `self`, as -# selected by the given block. +# * #select (aliased as #filter): Returns an array of member values from +# `self`, as selected by the given block. # * #values_at: Returns an array containing values for given member names. # # ### Methods for Assigning @@ -101,7 +101,7 @@ # # ### Methods for Converting # -# * #inspect, #to_s: Returns a string representation of `self`. +# * #inspect (aliased as #to_s): Returns a string representation of `self`. # * #to_h: Returns a hash of the member name/value pairs in `self`. # class Struct[Elem] diff --git a/core/symbol.rbs b/core/symbol.rbs index b9c5ca9d1d..5589f93701 100644 --- a/core/symbol.rbs +++ b/core/symbol.rbs @@ -1,14 +1,14 @@ # -# Symbol objects represent named identifiers inside the Ruby interpreter. +# A `Symbol` object represents a named identifier inside the Ruby interpreter. # -# You can create a Symbol object explicitly with: +# You can create a `Symbol` object explicitly with: # # * A [symbol literal](rdoc-ref:syntax/literals.rdoc@Symbol+Literals). # -# The same Symbol object will be created for a given name or string for the +# The same `Symbol` object will be created for a given name or string for the # duration of a program's execution, regardless of the context or meaning of # that name. Thus if `Fred` is a constant in one context, a method in another, -# and a class in a third, the Symbol `:Fred` will be the same object in all +# and a class in a third, the `Symbol` `:Fred` will be the same object in all # three contexts. # # module One @@ -51,17 +51,17 @@ # local_variables # # => [:seven] # -# Symbol objects are different from String objects in that Symbol objects -# represent identifiers, while String objects represent text or data. +# A `Symbol` object differs from a String object in that a `Symbol` object +# represents an identifier, while a String object represents text or data. # # ## What's Here # -# First, what's elsewhere. Class Symbol: +# First, what's elsewhere. Class `Symbol`: # # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). # * Includes [module Comparable](rdoc-ref:Comparable@What-27s+Here). # -# Here, class Symbol provides methods that are useful for: +# Here, class `Symbol` provides methods that are useful for: # # * [Querying](rdoc-ref:Symbol@Methods+for+Querying) # * [Comparing](rdoc-ref:Symbol@Methods+for+Comparing) @@ -305,12 +305,10 @@ class Symbol # def end_with?: (*string suffixes) -> bool - # - # Returns a string representation of `self` (not including the leading colon): - # - # :foo.to_s # => "foo" - # - # Related: Symbol#inspect, Symbol#name. + # # alias id2name to_s @@ -370,7 +368,7 @@ class Symbol def next: () -> Symbol # # Returns a frozen string representation of `self` (not including the leading @@ -441,7 +439,7 @@ class Symbol def to_proc: () -> Proc # # Returns a string representation of `self` (not including the leading colon): diff --git a/core/thread.rbs b/core/thread.rbs index 563cd9984e..f5b3d6b611 100644 --- a/core/thread.rbs +++ b/core/thread.rbs @@ -822,7 +822,7 @@ class Thread < Object # # Yields each frame of the current execution stack as a backtrace location # object. @@ -928,30 +928,6 @@ class Thread < Object # resource allocation code. Then, the ensure block is where we can safely # deallocate your resources. # - # #### Guarding from Timeout::Error - # - # In the next example, we will guard from the Timeout::Error exception. This - # will help prevent from leaking resources when Timeout::Error exceptions occur - # during normal ensure clause. For this example we use the help of the standard - # library Timeout, from lib/timeout.rb - # - # require 'timeout' - # Thread.handle_interrupt(Timeout::Error => :never) { - # timeout(10){ - # # Timeout::Error doesn't occur here - # Thread.handle_interrupt(Timeout::Error => :on_blocking) { - # # possible to be killed by Timeout::Error - # # while blocking operation - # } - # # Timeout::Error doesn't occur here - # } - # } - # - # In the first part of the `timeout` block, we can rely on Timeout::Error being - # ignored. Then in the `Timeout::Error => :on_blocking` block, any operation - # that will block the calling thread is susceptible to a Timeout::Error - # exception being raised. - # # #### Stack control settings # # It's possible to stack multiple levels of ::handle_interrupt blocks in order @@ -1322,9 +1298,28 @@ class Thread::Backtrace::Location # rdoc-file=vm_backtrace.c # - base_label() # --> - # Returns the base label of this frame. + # Returns the base label of this frame, which is usually equal to the label, + # without decoration. + # + # Consider the following example: + # + # def foo + # puts caller_locations(0).first.base_label + # + # 1.times do + # puts caller_locations(0).first.base_label # - # Usually same as #label, without decoration. + # 1.times do + # puts caller_locations(0).first.base_label + # end + # end + # end + # + # The result of calling `foo` is this: + # + # foo + # foo + # foo # def base_label: () -> String? @@ -1347,15 +1342,14 @@ class Thread::Backtrace::Location # 1.times do # puts caller_locations(0).first.label # end - # # end # end # # The result of calling `foo` is this: # - # label: foo - # label: block in foo - # label: block (2 levels) in foo + # foo + # block in foo + # block (2 levels) in foo # def label: () -> String? diff --git a/core/time.rbs b/core/time.rbs index c6c7ae69f9..57bb067027 100644 --- a/core/time.rbs +++ b/core/time.rbs @@ -45,6 +45,42 @@ # A `Time` object derived from the system clock (for example, by method # Time.now) has the resolution supported by the system. # +# ## Time Internal Representation +# +# Time implementation uses a signed 63 bit integer, Integer, or Rational. It is +# a number of nanoseconds since the *Epoch*. The signed 63 bit integer can +# represent 1823-11-12 to 2116-02-20. When Integer or Rational is used (before +# 1823, after 2116, under nanosecond), Time works slower than when the signed 63 +# bit integer is used. +# +# Ruby uses the C function `localtime` and `gmtime` to map between the number +# and 6-tuple (year,month,day,hour,minute,second). `localtime` is used for local +# time and "gmtime" is used for UTC. +# +# Integer and Rational has no range limit, but the localtime and gmtime has +# range limits due to the C types `time_t` and `struct tm`. If that limit is +# exceeded, Ruby extrapolates the localtime function. +# +# The Time class always uses the Gregorian calendar. I.e. the proleptic +# Gregorian calendar is used. Other calendars, such as Julian calendar, are not +# supported. +# +# `time_t` can represent 1901-12-14 to 2038-01-19 if it is 32 bit signed +# integer, -292277022657-01-27 to 292277026596-12-05 if it is 64 bit signed +# integer. However `localtime` on some platforms doesn't supports negative +# `time_t` (before 1970). +# +# `struct tm` has *tm_year* member to represent years. (`tm_year = 0` means the +# year 1900.) It is defined as `int` in the C standard. *tm_year* can represent +# between -2147481748 to 2147485547 if `int` is 32 bit. +# +# Ruby supports leap seconds as far as if the C function `localtime` and +# `gmtime` supports it. They use the tz database in most Unix systems. The tz +# database has timezones which supports leap seconds. For example, "Asia/Tokyo" +# doesn't support leap seconds but "right/Asia/Tokyo" supports leap seconds. So, +# Ruby supports leap seconds if the TZ environment variable is set to +# "right/Asia/Tokyo" in most Unix systems. +# # ## Examples # # All of these examples were done using the EST timezone which is GMT-5. @@ -129,12 +165,12 @@ # # Here, class `Time` provides methods that are useful for: # -# * {Creating `Time`[objects}](rdoc-ref:Time@Methods+for+Creating). -# * {Fetching `Time`[values}](rdoc-ref:Time@Methods+for+Fetching). -# * {Querying a `Time`[object}](rdoc-ref:Time@Methods+for+Querying). -# * {Comparing `Time`[objects}](rdoc-ref:Time@Methods+for+Comparing). -# * {Converting a `Time`[object}](rdoc-ref:Time@Methods+for+Converting). -# * {Rounding a `Time`[}](rdoc-ref:Time@Methods+for+Rounding). +# * [Creating Time objects](rdoc-ref:Time@Methods+for+Creating). +# * [Fetching Time values](rdoc-ref:Time@Methods+for+Fetching). +# * [Querying a Time object](rdoc-ref:Time@Methods+for+Querying). +# * [Comparing Time objects](rdoc-ref:Time@Methods+for+Comparing). +# * [Converting a Time object](rdoc-ref:Time@Methods+for+Converting). +# * [Rounding a Time](rdoc-ref:Time@Methods+for+Rounding). # # ### Methods for Creating # @@ -278,43 +314,68 @@ # # * `local_to_utc`: # -# * Called when Time.new is invoked with `tz` as the value of positional -# argument `zone` or keyword argument `in:`. -# * Argument: a [Time-like object](rdoc-ref:Time@Time-Like+Objects). -# * Returns: a [Time-like object](rdoc-ref:Time@Time-Like+Objects) in the -# UTC timezone. +# Called when Time.new is invoked with `tz` as the value of positional +# argument `zone` or keyword argument `in:`. +# +# Argument +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects). +# +# Returns +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects) in the UTC +# timezone. +# # # * `utc_to_local`: # -# * Called when Time.at or Time.now is invoked with `tz` as the value for -# keyword argument `in:`, and when Time#getlocal or Time#localtime is -# called with `tz` as the value for positional argument `zone`. -# * Argument: a [Time-like object](rdoc-ref:Time@Time-Like+Objects). -# * Returns: a [Time-like object](rdoc-ref:Time@Time-Like+Objects) in the -# local timezone. +# Called when Time.at or Time.now is invoked with `tz` as the value for +# keyword argument `in:`, and when Time#getlocal or Time#localtime is called +# with `tz` as the value for positional argument `zone`. +# +# Argument +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects). +# +# Returns +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects) in the local +# timezone. +# # # A custom timezone class may have these instance methods, which will be called # if defined: # # * `abbr`: # -# * Called when Time#strftime is invoked with a format involving `%Z`. -# * Argument: a [Time-like object](rdoc-ref:Time@Time-Like+Objects). -# * Returns: a string abbreviation for the timezone name. +# Called when Time#strftime is invoked with a format involving `%Z`. +# +# Argument +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects). +# +# Returns +# : a string abbreviation for the timezone name. +# # # * `dst?`: # -# * Called when Time.at or Time.now is invoked with `tz` as the value for -# keyword argument `in:`, and when Time#getlocal or Time#localtime is -# called with `tz` as the value for positional argument `zone`. -# * Argument: a [Time-like object](rdoc-ref:Time@Time-Like+Objects). -# * Returns: whether the time is daylight saving time. +# Called when Time.at or Time.now is invoked with `tz` as the value for +# keyword argument `in:`, and when Time#getlocal or Time#localtime is called +# with `tz` as the value for positional argument `zone`. +# +# Argument +# : a [Time-like object](rdoc-ref:Time@Time-Like+Objects). +# +# Returns +# : whether the time is daylight saving time. +# # # * `name`: # -# * Called when `Marshal.dump(t)` is invoked -# * Argument: none. -# * Returns: the string name of the timezone. +# Called when `Marshal.dump(t)` is invoked +# +# Argument +# : none. +# +# Returns +# : the string name of the timezone. +# # # #### `Time`-Like Objects # diff --git a/core/warning.rbs b/core/warning.rbs index 006e12a32e..d5fcddfe34 100644 --- a/core/warning.rbs +++ b/core/warning.rbs @@ -50,7 +50,6 @@ module Warning # # `:experimental` # : experimental features - # * Pattern matching # # # `:performance` diff --git a/stdlib/benchmark/0/benchmark.rbs b/stdlib/benchmark/0/benchmark.rbs index ba6ea60eda..fdb43931b5 100644 --- a/stdlib/benchmark/0/benchmark.rbs +++ b/stdlib/benchmark/0/benchmark.rbs @@ -240,7 +240,11 @@ module Benchmark # rdoc-file=lib/benchmark.rb # - realtime() { || ... } # --> - # Returns the elapsed real time used to execute the given block. + # Returns the elapsed real time used to execute the given block. The unit of + # time is seconds. + # + # Benchmark.realtime { "a" * 1_000_000_000 } + # #=> 0.5098029999935534 # def self?.realtime: () { () -> void } -> Float diff --git a/stdlib/bigdecimal/0/big_decimal.rbs b/stdlib/bigdecimal/0/big_decimal.rbs index 64166d272d..15abd15df3 100644 --- a/stdlib/bigdecimal/0/big_decimal.rbs +++ b/stdlib/bigdecimal/0/big_decimal.rbs @@ -1,152 +1,3 @@ -# -# BigDecimal provides arbitrary-precision floating point decimal arithmetic. -# -# ## Introduction -# -# Ruby provides built-in support for arbitrary precision integer arithmetic. -# -# For example: -# -# 42**13 #=> 1265437718438866624512 -# -# BigDecimal provides similar support for very large or very accurate floating -# point numbers. -# -# Decimal arithmetic is also useful for general calculation, because it provides -# the correct answers people expect--whereas normal binary floating point -# arithmetic often introduces subtle errors because of the conversion between -# base 10 and base 2. -# -# For example, try: -# -# sum = 0 -# 10_000.times do -# sum = sum + 0.0001 -# end -# print sum #=> 0.9999999999999062 -# -# and contrast with the output from: -# -# require 'bigdecimal' -# -# sum = BigDecimal("0") -# 10_000.times do -# sum = sum + BigDecimal("0.0001") -# end -# print sum #=> 0.1E1 -# -# Similarly: -# -# (BigDecimal("1.2") - BigDecimal("1.0")) == BigDecimal("0.2") #=> true -# -# (1.2 - 1.0) == 0.2 #=> false -# -# ## A Note About Precision -# -# For a calculation using a BigDecimal and another `value`, the precision of the -# result depends on the type of `value`: -# -# * If `value` is a Float, the precision is Float::DIG + 1. -# * If `value` is a Rational, the precision is larger than Float::DIG + 1. -# * If `value` is a BigDecimal, the precision is `value`'s precision in the -# internal representation, which is platform-dependent. -# * If `value` is other object, the precision is determined by the result of -# +BigDecimal(value)+. -# -# ## Special features of accurate decimal arithmetic -# -# Because BigDecimal is more accurate than normal binary floating point -# arithmetic, it requires some special values. -# -# ### Infinity -# -# BigDecimal sometimes needs to return infinity, for example if you divide a -# value by zero. -# -# BigDecimal("1.0") / BigDecimal("0.0") #=> Infinity -# BigDecimal("-1.0") / BigDecimal("0.0") #=> -Infinity -# -# You can represent infinite numbers to BigDecimal using the strings -# `'Infinity'`, `'+Infinity'` and `'-Infinity'` (case-sensitive) -# -# ### Not a Number -# -# When a computation results in an undefined value, the special value `NaN` (for -# 'not a number') is returned. -# -# Example: -# -# BigDecimal("0.0") / BigDecimal("0.0") #=> NaN -# -# You can also create undefined values. -# -# NaN is never considered to be the same as any other value, even NaN itself: -# -# n = BigDecimal('NaN') -# n == 0.0 #=> false -# n == n #=> false -# -# ### Positive and negative zero -# -# If a computation results in a value which is too small to be represented as a -# BigDecimal within the currently specified limits of precision, zero must be -# returned. -# -# If the value which is too small to be represented is negative, a BigDecimal -# value of negative zero is returned. -# -# BigDecimal("1.0") / BigDecimal("-Infinity") #=> -0.0 -# -# If the value is positive, a value of positive zero is returned. -# -# BigDecimal("1.0") / BigDecimal("Infinity") #=> 0.0 -# -# (See BigDecimal.mode for how to specify limits of precision.) -# -# Note that `-0.0` and `0.0` are considered to be the same for the purposes of -# comparison. -# -# Note also that in mathematics, there is no particular concept of negative or -# positive zero; true mathematical zero has no sign. -# -# ## bigdecimal/util -# -# When you require `bigdecimal/util`, the #to_d method will be available on -# BigDecimal and the native Integer, Float, Rational, and String classes: -# -# require 'bigdecimal/util' -# -# 42.to_d # => 0.42e2 -# 0.5.to_d # => 0.5e0 -# (2/3r).to_d(3) # => 0.667e0 -# "0.5".to_d # => 0.5e0 -# -# ## Methods for Working with JSON -# -# * [::json_create](rdoc-ref:BigDecimal.json_create): Returns a new BigDecimal -# object constructed from the given object. -# * [#as_json](rdoc-ref:BigDecimal#as_json): Returns a 2-element hash -# representing `self`. -# * [#to_json](rdoc-ref:BigDecimal#to_json): Returns a JSON string -# representing `self`. -# -# These methods are provided by the [JSON gem](https://github.com/flori/json). -# To make these methods available: -# -# require 'json/add/bigdecimal' -# -# * ## License -# -# Copyright (C) 2002 by Shigeo Kobayashi . -# -# BigDecimal is released under the Ruby and 2-clause BSD licenses. See -# LICENSE.txt for details. -# -# Maintained by mrkn and ruby-core members. -# -# Documented by zzak , mathew , and -# many other contributors. -# class BigDecimal < Numeric # # 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.rect(2, 3) / Complex.rect(2, 3) # => (1+0i) + # Complex.rect(900) / Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i) + # Complex.rect(9, 8) / 4 # => ((9/4)+2i) + # Complex.rect(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) # def /: (BigDecimal) -> Complex | ... @@ -1721,11 +1572,11 @@ class Complex # --> # 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.rect(2, 3) * Complex.rect(2, 3) # => (-5+12i) + # Complex.rect(900) * Complex.rect(1) # => (900+0i) + # Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i) + # Complex.rect(9, 8) * 4 # => (36+32i) + # Complex.rect(20, 9) * 9.8 # => (196.0+88.2i) # def *: (BigDecimal) -> Complex | ... @@ -1736,11 +1587,11 @@ class Complex # --> # 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.rect(2, 3) + Complex.rect(2, 3) # => (4+6i) + # Complex.rect(900) + Complex.rect(1) # => (901+0i) + # Complex.rect(-2, 9) + Complex.rect(-9, 2) # => (-11+11i) + # Complex.rect(9, 8) + 4 # => (13+8i) + # Complex.rect(20, 9) + 9.8 # => (29.8+9i) # def +: (BigDecimal) -> Complex | ... @@ -1751,11 +1602,11 @@ class Complex # --> # 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.rect(2, 3) - Complex.rect(2, 3) # => (0+0i) + # Complex.rect(900) - Complex.rect(1) # => (899+0i) + # Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i) + # Complex.rect(9, 8) - 4 # => (5+8i) + # Complex.rect(20, 9) - 9.8 # => (10.2+9i) # def -: (BigDecimal) -> Complex | ... diff --git a/stdlib/date/0/date.rbs b/stdlib/date/0/date.rbs index 79f5c33578..8366fbeca2 100644 --- a/stdlib/date/0/date.rbs +++ b/stdlib/date/0/date.rbs @@ -743,10 +743,10 @@ class Date # rdoc-file=ext/date/date_core.c # - d - other -> date or rational # --> - # Returns the difference between the two dates if the other is a date object. - # If the other is a numeric value, returns a date object pointing `other` days - # before self. If the other is a fractional number, assumes its precision is at - # most nanosecond. + # If the other is a date object, returns a Rational whose value is the + # difference between the two dates in days. If the other is a numeric value, + # returns a date object pointing `other` days before self. If the other is a + # fractional number, assumes its precision is at most nanosecond. # # Date.new(2001,2,3) - 1 #=> # # DateTime.new(2001,2,3) - Rational(1,2) diff --git a/stdlib/digest/0/digest.rbs b/stdlib/digest/0/digest.rbs index a9e7b0e232..0915a5541b 100644 --- a/stdlib/digest/0/digest.rbs +++ b/stdlib/digest/0/digest.rbs @@ -400,7 +400,7 @@ end # }; # # rb_ivar_set(cDigest_SHA1, rb_intern("metadata"), -# Data_Wrap_Struct(0, 0, 0, (void *)&sha1)); +# rb_digest_make_metadata(&sha1)); # class Digest::Base < Digest::Class # @@ -523,12 +523,33 @@ end class Digest::RMD160 < Digest::Base end +# +# Classes for calculating message digests using the SHA-256/384/512 Secure Hash +# Algorithm(s) by NIST (the US' National Institute of Standards and Technology), +# described in FIPS PUB 180-2. +# +# See SHA2. +# class Digest::SHA256 < Digest::Base end +# +# Classes for calculating message digests using the SHA-256/384/512 Secure Hash +# Algorithm(s) by NIST (the US' National Institute of Standards and Technology), +# described in FIPS PUB 180-2. +# +# See SHA2. +# class Digest::SHA384 < Digest::Base end +# +# Classes for calculating message digests using the SHA-256/384/512 Secure Hash +# Algorithm(s) by NIST (the US' National Institute of Standards and Technology), +# described in FIPS PUB 180-2. +# +# See SHA2. +# class Digest::SHA512 < Digest::Base end diff --git a/stdlib/etc/0/etc.rbs b/stdlib/etc/0/etc.rbs index 5fd90f59e8..a98febca62 100644 --- a/stdlib/etc/0/etc.rbs +++ b/stdlib/etc/0/etc.rbs @@ -9,7 +9,7 @@ # The Etc module provides a more reliable way to access information about the # logged in user than environment variables such as +$USER+. # -# ## Example: +# **Example:** # # require 'etc' # @@ -27,7 +27,7 @@ module Etc # # Returns system configuration variable using confstr(). # @@ -46,7 +46,7 @@ module Etc # # Ends the process of scanning through the `/etc/group` file begun by # ::getgrent, and closes the file. @@ -55,7 +55,7 @@ module Etc # # Ends the process of scanning through the `/etc/passwd` file begun with # ::getpwent, and closes the file. @@ -64,7 +64,7 @@ module Etc # # Returns an entry from the `/etc/group` file. # @@ -80,7 +80,7 @@ module Etc # # Returns information about the group with specified integer `group_id`, as # found in `/etc/group`. @@ -89,7 +89,7 @@ module Etc # # See the unix manpage for `getgrgid(3)` for more detail. # - # ### Example: + # **Example:** # # Etc.getgrgid(100) # #=> # @@ -98,7 +98,7 @@ module Etc # # Returns information about the group with specified `name`, as found in # `/etc/group`. @@ -107,7 +107,7 @@ module Etc # # See the unix manpage for `getgrnam(3)` for more detail. # - # ### Example: + # **Example:** # # Etc.getgrnam('users') # #=> # @@ -134,7 +134,7 @@ module Etc # # Returns an entry from the `/etc/passwd` file. # @@ -150,7 +150,7 @@ module Etc # # Returns the `/etc/passwd` information for the user with specified login # `name`. @@ -159,7 +159,7 @@ module Etc # # See the unix manpage for `getpwnam(3)` for more detail. # - # ### Example: + # **Example:** # # Etc.getpwnam('root') # #=> # @@ -168,7 +168,7 @@ module Etc # # Returns the `/etc/passwd` information for the user with the given integer # `uid`. @@ -179,7 +179,7 @@ module Etc # # See the unix manpage for `getpwuid(3)` for more detail. # - # ### Example: + # **Example:** # # Etc.getpwuid(0) # #=> # @@ -188,7 +188,8 @@ module Etc # # Provides a convenient Ruby iterator which executes a block for each entry in # the `/etc/group` file. @@ -197,7 +198,7 @@ module Etc # # See ::getgrent above for details. # - # Example: + # **Example:** # # require 'etc' # @@ -210,7 +211,7 @@ module Etc # # Returns the number of online processors. # @@ -222,7 +223,7 @@ module Etc # * sysconf(_SC_NPROCESSORS_ONLN): GNU/Linux, NetBSD, FreeBSD, OpenBSD, # DragonFly BSD, OpenIndiana, Mac OS X, AIX # - # Example: + # **Example:** # # require 'etc' # p Etc.nprocessors #=> 4 @@ -231,7 +232,7 @@ module Etc # process is bound to specific cpus. This is intended for getting better # parallel processing. # - # Example: (Linux) + # **Example:** (Linux) # # linux$ taskset 0x3 ./ruby -retc -e "p Etc.nprocessors" #=> 2 # @@ -239,8 +240,8 @@ module Etc # # Provides a convenient Ruby iterator which executes a block for each entry in # the `/etc/passwd` file. @@ -249,7 +250,7 @@ module Etc # # See ::getpwent above for details. # - # Example: + # **Example:** # # require 'etc' # @@ -262,7 +263,7 @@ module Etc # # Resets the process of reading the `/etc/group` file, so that the next call to # ::getgrent will return the first entry again. @@ -271,7 +272,7 @@ module Etc # # Resets the process of reading the `/etc/passwd` file, so that the next call to # ::getpwent will return the first entry again. @@ -280,7 +281,7 @@ module Etc # # Returns system configuration variable using sysconf(). # @@ -296,7 +297,7 @@ module Etc # # Returns system configuration directory. # @@ -310,7 +311,7 @@ module Etc # # Returns system temporary directory; typically "/tmp". # @@ -318,14 +319,14 @@ module Etc # # Returns the system information obtained by uname system call. # # The return value is a hash which has 5 keys at least: # :sysname, :nodename, :release, :version, :machine # - # Example: + # **Example:** # # require 'etc' # require 'pp' @@ -651,6 +652,9 @@ module Etc SC_XOPEN_VERSION: Integer + # + # The version + # VERSION: String # @@ -681,7 +685,7 @@ module Etc # # Iterates for each entry in the `/etc/group` file if a block is given. @@ -690,7 +694,7 @@ module Etc # # The code block is passed a Group struct. # - # Example: + # **Example:** # # require 'etc' # @@ -786,7 +790,7 @@ module Etc # # Iterates for each entry in the `/etc/passwd` file if a block is given. @@ -797,7 +801,7 @@ module Etc # # See Etc.getpwent above for details. # - # Example: + # **Example:** # # require 'etc' # diff --git a/stdlib/fileutils/0/fileutils.rbs b/stdlib/fileutils/0/fileutils.rbs index 7702bacc90..757ccca636 100644 --- a/stdlib/fileutils/0/fileutils.rbs +++ b/stdlib/fileutils/0/fileutils.rbs @@ -177,6 +177,9 @@ # 52). # module FileUtils + # + # The version number. + # VERSION: String type mode = Integer | String diff --git a/stdlib/io-console/0/io-console.rbs b/stdlib/io-console/0/io-console.rbs index 2895b7869f..ffa245d2e5 100644 --- a/stdlib/io-console/0/io-console.rbs +++ b/stdlib/io-console/0/io-console.rbs @@ -39,22 +39,33 @@ class IO # + # Beeps on the output console. + # + # You must require 'io/console' to use this method. # def beep: () -> self # + # Yields while console input events are queued. + # + # This method is Windows only. + # + # You must require 'io/console' to use this method. # def check_winsize_changed: () { () -> void } -> self # + # Clears the entire screen and moves the cursor top-left corner. + # + # You must require 'io/console' to use this method. # def clear_screen: () -> self @@ -119,36 +130,53 @@ class IO # + # Same as `io.goto(line, column)` + # + # See IO#goto. + # + # You must require 'io/console' to use this method. # def cursor=: ([ Integer, Integer ]) -> [ Integer, Integer ] # + # Moves the cursor down `n` lines. + # + # You must require 'io/console' to use this method. # def cursor_down: (int) -> self # + # Moves the cursor left `n` columns. + # + # You must require 'io/console' to use this method. # def cursor_left: (int) -> self # + # Moves the cursor right `n` columns. + # + # You must require 'io/console' to use this method. # def cursor_right: (int) -> self # + # Moves the cursor up `n` lines. + # + # You must require 'io/console' to use this method. # def cursor_up: (int) -> self @@ -175,15 +203,23 @@ class IO # + # Erases the line at the cursor corresponding to `mode`. `mode` may be either: + # 0: after cursor 1: before and cursor 2: entire line + # + # You must require 'io/console' to use this method. # def erase_line: (0 | 1 | 2 | nil) -> self # + # Erases the screen at the cursor corresponding to `mode`. `mode` may be either: + # 0: after cursor 1: before and cursor 2: entire screen + # + # You must require 'io/console' to use this method. # def erase_screen: (0 | 1 | 2 | 3 | nil) -> self @@ -220,15 +256,21 @@ class IO # + # Set the cursor position at `line` and `column`. + # + # You must require 'io/console' to use this method. # def goto: (int, int) -> self # + # Set the cursor position at `column` in the same line of the current position. + # + # You must require 'io/console' to use this method. # def goto_column: (int) -> self @@ -278,8 +320,14 @@ class IO # + # Returns `true` if `key` is pressed. `key` may be a virtual key code or its + # name (String or Symbol) with out "VK_" prefix. + # + # This method is Windows only. + # + # You must require 'io/console' to use this method. # def pressed?: (Integer | interned) -> bool @@ -324,15 +372,21 @@ class IO # + # Scrolls the entire scrolls backward `n` lines. + # + # You must require 'io/console' to use this method. # def scroll_backward: (int) -> self # + # Scrolls the entire scrolls forward `n` lines. + # + # You must require 'io/console' to use this method. # def scroll_forward: (int) -> self diff --git a/stdlib/ipaddr/0/ipaddr.rbs b/stdlib/ipaddr/0/ipaddr.rbs index 70f3034b82..600c535247 100644 --- a/stdlib/ipaddr/0/ipaddr.rbs +++ b/stdlib/ipaddr/0/ipaddr.rbs @@ -37,7 +37,8 @@ class IPAddr # - ntop(addr) # --> # Convert a network byte ordered string form of an IP address into human - # readable form. + # readable form. It expects the string to be encoded in Encoding::ASCII_8BIT + # (BINARY). # def self.ntop: (String addr) -> String @@ -240,8 +241,10 @@ class IPAddr # - link_local?() # --> # Returns true if the ipaddr is a link-local address. IPv4 addresses in - # 169.254.0.0/16 reserved by RFC 3927 and Link-Local IPv6 Unicast Addresses in - # fe80::/10 reserved by RFC 4291 are considered link-local. + # 169.254.0.0/16 reserved by RFC 3927 and link-local IPv6 Unicast Addresses in + # fe80::/10 reserved by RFC 4291 are considered link-local. Link-local IPv4 + # addresses in the IPv4-mapped IPv6 address range are also considered + # link-local. # def link_local?: () -> bool @@ -249,7 +252,8 @@ class IPAddr # rdoc-file=lib/ipaddr.rb # - loopback?() # --> - # Returns true if the ipaddr is a loopback address. + # Returns true if the ipaddr is a loopback address. Loopback IPv4 addresses in + # the IPv4-mapped IPv6 address range are also considered as loopback addresses. # def loopback?: () -> bool diff --git a/stdlib/json/0/json.rbs b/stdlib/json/0/json.rbs index 854d021145..ca8963b6cb 100644 --- a/stdlib/json/0/json.rbs +++ b/stdlib/json/0/json.rbs @@ -473,13 +473,13 @@ type json_state = singleton(JSON::Ext::Generator::State) | singleton(JSON::Pure: # json1 = JSON.generate(ruby) # ruby1 = JSON.parse(json1, create_additions: true) # # Make a nice display. -# display = < # Sets or returns the default options for the JSON.dump method. Initially: # opts = JSON.dump_default_options - # opts # => {:max_nesting=>false, :allow_nan=>true, :script_safe=>false} + # opts # => {:max_nesting=>false, :allow_nan=>true} # def self.dump_default_options: () -> json_options # # Sets or returns the default options for the JSON.dump method. Initially: # opts = JSON.dump_default_options - # opts # => {:max_nesting=>false, :allow_nan=>true, :script_safe=>false} + # opts # => {:max_nesting=>false, :allow_nan=>true} # def self.dump_default_options=: (json_options) -> json_options @@ -822,9 +822,7 @@ module JSON def self?.generate: (_ToJson obj, ?json_options opts) -> String # - # Returns the JSON generator module that is used by JSON. This is either - # JSON::Ext::Generator or JSON::Pure::Generator: - # JSON.generator # => JSON::Ext::Generator + # Returns the JSON generator module that is used by JSON. # def self.generator: () -> json_generator @@ -844,6 +842,15 @@ module JSON # --> # Returns the Ruby objects created by parsing the given `source`. # + # BEWARE: This method is meant to serialise data from trusted user input, like + # from your own database server or clients under your control, it could be + # dangerous to allow untrusted users to pass JSON sources into it. If you must + # use it, use JSON.unsafe_load instead to make it clear. + # + # Since JSON version 2.8.0, `load` emits a deprecation warning when a non native + # type is deserialized, without `create_additions` being explicitly enabled, and + # in JSON version 3.0, `load` will have `create_additions` disabled by default. + # # * Argument `source` must be, or be convertible to, a String: # * If `source` responds to instance method `to_str`, `source.to_str` # becomes the source. @@ -857,10 +864,7 @@ module JSON # * Otherwise, `source` remains the source. # * Argument `proc`, if given, must be a Proc that accepts one argument. It # will be called recursively with each result (depth-first order). See - # details below. BEWARE: This method is meant to serialise data from trusted - # user input, like from your own database server or clients under your - # control, it could be dangerous to allow untrusted users to pass JSON - # sources into it. + # details below. # * Argument `opts`, if given, contains a Hash of options for the parsing. See # [Parsing Options](#module-JSON-label-Parsing+Options). The default options # can be changed via method JSON.load_default_options=. @@ -871,17 +875,17 @@ module JSON # `parse(source, opts)`; see #parse. # # Source for following examples: - # source = <<-EOT - # { - # "name": "Dave", - # "age" :40, - # "hats": [ - # "Cattleman's", - # "Panama", - # "Tophat" - # ] - # } - # EOT + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON # # Load a String: # ruby = JSON.load(source) @@ -1035,17 +1039,17 @@ module JSON # \JSON](#module-JSON-label-Parsing+JSON). # # Parses nested JSON objects: - # source = <<-EOT - # { - # "name": "Dave", - # "age" :40, - # "hats": [ - # "Cattleman's", - # "Panama", - # "Tophat" - # ] - # } - # EOT + # source = <<~JSON + # { + # "name": "Dave", + # "age" :40, + # "hats": [ + # "Cattleman's", + # "Panama", + # "Tophat" + # ] + # } + # JSON # ruby = JSON.parse(source) # ruby # => {"name"=>"Dave", "age"=>40, "hats"=>["Cattleman's", "Panama", "Tophat"]} # @@ -1074,9 +1078,7 @@ module JSON def self?.parse!: (string source, ?json_options opts) -> untyped # - # Returns the JSON parser class that is used by JSON. This is either - # JSON::Ext::Parser or JSON::Pure::Parser: - # JSON.parser # => JSON::Ext::Parser + # Returns the JSON parser class that is used by JSON. # def self.parser: () -> json_parser @@ -1127,29 +1129,25 @@ module JSON # # alias self.restore self.load # # alias restore load # - # Sets or Returns the JSON generator state class that is used by JSON. This is - # either JSON::Ext::Generator::State or JSON::Pure::Generator::State: - # JSON.state # => JSON::Ext::Generator::State + # Sets or Returns the JSON generator state class that is used by JSON. # def self.state: () -> json_state # - # Sets or Returns the JSON generator state class that is used by JSON. This is - # either JSON::Ext::Generator::State or JSON::Pure::Generator::State: - # JSON.state # => JSON::Ext::Generator::State + # Sets or Returns the JSON generator state class that is used by JSON. # def self.state=: (json_state) -> json_state @@ -1172,9 +1170,6 @@ JSON::PRETTY_STATE_PROTOTYPE: json_state JSON::SAFE_STATE_PROTOTYPE: json_state -# -# JSON version -# JSON::VERSION: String JSON::VERSION_ARRAY: Array[Integer] diff --git a/stdlib/logger/0/log_device.rbs b/stdlib/logger/0/log_device.rbs index 508abc588a..20e33ca25d 100644 --- a/stdlib/logger/0/log_device.rbs +++ b/stdlib/logger/0/log_device.rbs @@ -57,7 +57,7 @@ class Logger # # def initialize: (?untyped logdev, ?binmode: boolish, ?shift_period_suffix: String, ?shift_size: Integer, ?shift_age: Numeric | String) -> void diff --git a/stdlib/logger/0/logger.rbs b/stdlib/logger/0/logger.rbs index 82c747e7ba..82228660b2 100644 --- a/stdlib/logger/0/logger.rbs +++ b/stdlib/logger/0/logger.rbs @@ -779,6 +779,9 @@ class Logger # * `shift_period_suffix`: sets the format for the filename suffix for # periodic log file rotation; default is `'%Y%m%d'`. See [Periodic # Rotation](rdoc-ref:Logger@Periodic+Rotation). + # * `reraise_write_errors`: An array of exception classes, which will be + # reraised if there is an error when writing to the log device. The default + # is to swallow all exceptions raised. # def initialize: (logdev? logdev, ?Numeric | String shift_age, ?Integer shift_size, ?shift_period_suffix: String, ?binmode: boolish, ?datetime_format: String, ?formatter: _Formatter, ?progname: String, ?level: Integer | interned) -> void end diff --git a/stdlib/net-http/0/net-http.rbs b/stdlib/net-http/0/net-http.rbs index 1a202d9461..9d70684d89 100644 --- a/stdlib/net-http/0/net-http.rbs +++ b/stdlib/net-http/0/net-http.rbs @@ -77,6 +77,8 @@ module Net # Net::HTTP.post(uri, data) # params = {title: 'foo', body: 'bar', userId: 1} # Net::HTTP.post_form(uri, params) + # data = '{"title": "foo", "body": "bar", "userId": 1}' + # Net::HTTP.put(uri, data) # # * If performance is important, consider using sessions, which lower request # overhead. This [session](rdoc-ref:Net::HTTP@Sessions) has multiple @@ -469,6 +471,10 @@ module Net # # ## What's Here # + # First, what's elsewhere. Class Net::HTTP: + # + # * Inherits from [class Object](rdoc-ref:Object@What-27s+Here). + # # This is a categorized summary of methods and attributes. # # ### Net::HTTP Objects @@ -526,6 +532,8 @@ module Net # form data and returns a response object. # * [::post](rdoc-ref:Net::HTTP.post): Sends a POST request with data and # returns a response object. + # * [::put](rdoc-ref:Net::HTTP.put): Sends a PUT request with data and returns + # a response object. # * [#copy](rdoc-ref:Net::HTTP#copy): Sends a COPY request and returns a # response object. # * [#delete](rdoc-ref:Net::HTTP#delete): Sends a DELETE request and returns a @@ -987,7 +995,7 @@ module Net # # Returns a new Net::HTTP object `http` (but does not open a TCP connection or # HTTP session). @@ -1677,6 +1685,11 @@ module Net # http = Net::HTTP.new(hostname) # http.put('/todos/1', data) # => # # + # Related: + # + # * Net::HTTP::Put: request class for HTTP method PUT. + # * Net::HTTP.put: sends PUT request, returns response body. + # def put: (String path, String data, ?headers initheader) -> Net::HTTPResponse # + # # Never `nil`. A boolean value indicating whether the encoding uses indefinite # length (in the case of parsing) or whether an indefinite length form shall be # used (in the encoding case). In DER, every value uses definite length form. @@ -948,7 +948,7 @@ module OpenSSL # def indefinite_length: () -> bool - # + # # Never `nil`. A boolean value indicating whether the encoding uses indefinite # length (in the case of parsing) or whether an indefinite length form shall be # used (in the encoding case). In DER, every value uses definite length form. @@ -965,7 +965,7 @@ module OpenSSL # def indefinite_length=: [U] (boolish) -> U - # + # # Never `nil`. A boolean value indicating whether the encoding uses indefinite # length (in the case of parsing) or whether an indefinite length form shall be # used (in the encoding case). In DER, every value uses definite length form. @@ -982,7 +982,7 @@ module OpenSSL # alias infinite_length indefinite_length - # + # # Never `nil`. A boolean value indicating whether the encoding uses indefinite # length (in the case of parsing) or whether an indefinite length form shall be # used (in the encoding case). In DER, every value uses definite length form. @@ -999,24 +999,24 @@ module OpenSSL # alias infinite_length= indefinite_length= - # + # # An Integer representing the tag number of this ASN1Data. Never `nil`. # def tag: () -> bn - # + # # An Integer representing the tag number of this ASN1Data. Never `nil`. # def tag=: (::Integer) -> ::Integer | (BN) -> BN - # + # # A Symbol representing the tag class of this ASN1Data. Never `nil`. See # ASN1Data for possible values. # def tag_class: () -> tag_class - # + # # A Symbol representing the tag class of this ASN1Data. Never `nil`. See # ASN1Data for possible values. # @@ -1033,13 +1033,13 @@ module OpenSSL # def to_der: () -> String - # + # # Carries the value of a ASN.1 type. Please confer Constructive and Primitive # for the mappings between ASN.1 data types and Ruby classes. # def value: () -> untyped - # + # # Carries the value of a ASN.1 type. Please confer Constructive and Primitive # for the mappings between ASN.1 data types and Ruby classes. # @@ -1048,7 +1048,7 @@ module OpenSSL private # # *value*: Please have a look at Constructive and Primitive to see how Ruby @@ -1120,7 +1120,7 @@ module OpenSSL include Enumerable[ASN1Data] # # Calls the given block once for each element in self, passing that element as @@ -1186,6 +1186,11 @@ module OpenSSL private + # + # def initialize: () -> void end @@ -1267,7 +1272,7 @@ module OpenSSL # rdoc-file=ext/openssl/ossl_asn1.c # - oid == other_oid => true or false # --> - # Returns `true` if *other_oid* is the same as *oid* + # Returns `true` if *other_oid* is the same as *oid*. # def ==: (ObjectId other) -> bool @@ -1848,7 +1853,7 @@ module OpenSSL # bignum is ignored. # * `10` - Decimal number representation, with a leading '-' for a # negative bignum. - # * `16` - Hexadeciaml number representation, with a leading '-' for a + # * `16` - Hexadecimal number representation, with a leading '-' for a # negative bignum. # def to_s: () -> String @@ -1898,7 +1903,7 @@ module OpenSSL # number. # * `10` - Decimal number representation, with a leading '-' for a # negative number. - # * `16` - Hexadeciaml number representation, with a leading '-' for a + # * `16` - Hexadecimal number representation, with a leading '-' for a # negative number. # def initialize: (instance) -> void @@ -2008,7 +2013,7 @@ module OpenSSL # # Reads the next "line" from the stream. Lines are separated by *eol*. If # *limit* is provided the result will not be longer than the given number of @@ -2666,8 +2671,8 @@ module OpenSSL # rdoc-file=ext/openssl/ossl_cipher.c # - cipher.name -> string # --> - # Returns the name of the cipher which may differ slightly from the original - # name provided. + # Returns the short name of the cipher which may differ slightly from the + # original name provided. # def name: () -> String @@ -3020,19 +3025,16 @@ module OpenSSL # --> # Gets the parsable form of the current configuration. # - # Given the following configuration being created: + # Given the following configuration file being loaded: # - # config = OpenSSL::Config.new - # #=> # - # config['default'] = {"foo"=>"bar","baz"=>"buz"} - # #=> {"foo"=>"bar", "baz"=>"buz"} + # config = OpenSSL::Config.load('baz.cnf') + # #=> # # puts config.to_s # #=> [ default ] # # foo=bar # # baz=buz # - # You can parse get the serialized configuration using #to_s and then parse it - # later: + # You can get the serialized configuration using #to_s and then parse it later: # # serialized_config = config.to_s # # much later... @@ -3217,7 +3219,8 @@ module OpenSSL # rdoc-file=ext/openssl/ossl_digest.c # - digest.name -> string # --> - # Returns the sn of this Digest algorithm. + # Returns the short name of this Digest algorithm which may differ slightly from + # the original name provided. # # ### Example # digest = OpenSSL::Digest.new('SHA512') @@ -3264,7 +3267,8 @@ module OpenSSL # - Digest.new(string [, data]) -> Digest # --> # Creates a Digest instance based on *string*, which is either the ln (long - # name) or sn (short name) of a supported digest algorithm. + # name) or sn (short name) of a supported digest algorithm. A list of supported + # algorithms can be obtained by calling OpenSSL::Digest.digests. # # If *data* (a String) is given, it is used as the initial input to the Digest # instance, i.e. @@ -3914,7 +3918,7 @@ module OpenSSL # - KDF.hkdf(ikm, salt:, info:, length:, hash:) -> String # --> # HMAC-based Extract-and-Expand Key Derivation Function (HKDF) as specified in - # [RFC 5869](https://tools.ietf.org/html/rfc5869). + # [RFC 5869](https://www.rfc-editor.org/rfc/rfc5869). # # New in OpenSSL 1.1.0. # @@ -3937,7 +3941,7 @@ module OpenSSL # # # ### Example - # # The values from https://datatracker.ietf.org/doc/html/rfc5869#appendix-A.1 + # # The values from https://www.rfc-editor.org/rfc/rfc5869#appendix-A.1 # ikm = ["0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b0b"].pack("H*") # salt = ["000102030405060708090a0b0c"].pack("H*") # info = ["f0f1f2f3f4f5f6f7f8f9"].pack("H*") @@ -3955,7 +3959,7 @@ module OpenSSL # *length* bytes. # # For more information about PBKDF2, see RFC 2898 Section 5.2 - # (https://tools.ietf.org/html/rfc2898#section-5.2). + # (https://www.rfc-editor.org/rfc/rfc2898#section-5.2). # # ### Parameters # pass @@ -3993,10 +3997,10 @@ module OpenSSL # attacks using custom hardwares than alternative KDFs such as PBKDF2 or bcrypt. # # The keyword arguments *N*, *r* and *p* can be used to tune scrypt. RFC 7914 - # (published on 2016-08, https://tools.ietf.org/html/rfc7914#section-2) states - # that using values r=8 and p=1 appears to yield good results. + # (published on 2016-08, https://www.rfc-editor.org/rfc/rfc7914#section-2) + # states that using values r=8 and p=1 appears to yield good results. # - # See RFC 7914 (https://tools.ietf.org/html/rfc7914) for more information. + # See RFC 7914 (https://www.rfc-editor.org/rfc/rfc7914) for more information. # # ### Parameters # pass @@ -4069,8 +4073,8 @@ module OpenSSL # # OpenSSL::Netscape is a namespace for SPKI (Simple Public Key Infrastructure) # which implements Signed Public Key and Challenge. See [RFC - # 2692](http://tools.ietf.org/html/rfc2692) and [RFC - # 2693](http://tools.ietf.org/html/rfc2692) for details. + # 2692](https://www.rfc-editor.org/rfc/rfc2692) and [RFC + # 2693](https://www.rfc-editor.org/rfc/rfc2692) for details. # module Netscape # @@ -5139,8 +5143,13 @@ module OpenSSL class PKCS7 # + # Creates a PKCS #7 enveloped-data structure. + # + # Before version 3.3.0, `cipher` was optional and defaulted to `"RC2-40-CBC"`. + # + # See also the man page PKCS7_encrypt(3). # def self.encrypt: (X509::Certificate certs, String data, ?Cipher cipher, ?Integer flags) -> instance @@ -8235,7 +8244,7 @@ module OpenSSL # # Gets various OpenSSL options. # @@ -8243,9 +8252,16 @@ module OpenSSL # - # Sets various OpenSSL options. + # Sets various OpenSSL options. The options are a bit field and can be combined + # with the bitwise OR operator (`|`). Available options are defined as constants + # in OpenSSL::SSL that begin with `OP_`. + # + # For backwards compatibility, passing `nil` has the same effect as passing + # OpenSSL::SSL::OP_ALL. + # + # See also man page SSL_CTX_set_options(3). # def options=: (Integer ssl_options) -> Integer @@ -11021,7 +11037,7 @@ module OpenSSL # - crl_uris() # --> # Get the distributionPoint fullName URI from the certificate's CRL distribution - # points extension, as described in RFC5280 Section 4.2.1.13 + # points extension, as described in RFC 5280 Section 4.2.1.13. # # Returns an array of strings or nil or raises ASN1::ASN1Error. # diff --git a/stdlib/optparse/0/optparse.rbs b/stdlib/optparse/0/optparse.rbs index 0449bf53e1..826404f389 100644 --- a/stdlib/optparse/0/optparse.rbs +++ b/stdlib/optparse/0/optparse.rbs @@ -429,6 +429,7 @@ class OptionParser # rdoc-file=lib/optparse.rb # - terminate(arg = nil) # --> + # See #terminate. # def self.terminate: (?String arg) -> bot @@ -436,6 +437,9 @@ class OptionParser # rdoc-file=lib/optparse.rb # - top() # --> + # Returns the global top option list. + # + # Do not use directly. # def self.top: () -> OptionParser::List @@ -456,6 +460,13 @@ class OptionParser # rdoc-file=lib/optparse.rb # - abort(mesg = $!) # --> + # Shows message with the program name then aborts. + # + # `mesg` + # : Message, defaulted to +$!+. + # + # + # See Kernel#abort. # def abort: (?_ToS mesg) -> bot @@ -504,6 +515,7 @@ class OptionParser # rdoc-file=lib/optparse.rb # - candidate(word) # --> + # Return candidates for `word`. # def candidate: (String word) -> Array[untyped] @@ -588,7 +600,7 @@ class OptionParser # # Parses environment variable `env` or its uppercase with splitting like a # shell. @@ -599,7 +611,7 @@ class OptionParser # # Wrapper method for getopts.rb. # @@ -635,12 +647,13 @@ class OptionParser # rdoc-file=lib/optparse.rb # - inc(*args) # --> + # See self.inc # def inc: (*untyped args) -> untyped # # Loads options from file names as `filename`. Does nothing when the file is not # present. Returns whether successfully loaded. @@ -674,6 +687,9 @@ class OptionParser # --> # Pushes a new List. # + # If a block is given, yields `self` and returns the result of the block, + # otherwise returns `self`. + # def new: () -> self | [T] () { (self) -> T } -> T @@ -740,7 +756,7 @@ class OptionParser # # Parses command line arguments `argv` in order. When a block is given, each # non-option argument is yielded. When optional `into` keyword argument is @@ -754,7 +770,7 @@ class OptionParser # # Same as #order, but removes switches destructively. Non-option arguments # remain in `argv`. @@ -763,7 +779,7 @@ class OptionParser # # Parses command line arguments `argv` in order when environment variable # POSIXLY_CORRECT is set, and in permutation mode otherwise. When optional @@ -775,7 +791,7 @@ class OptionParser # # Same as #parse, but removes switches destructively. Non-option arguments # remain in `argv`. @@ -784,7 +800,7 @@ class OptionParser # # Parses command line arguments `argv` in permutation mode and returns list of # non-option arguments. When optional `into` keyword argument is provided, the @@ -796,7 +812,7 @@ class OptionParser # # Same as #permute, but removes switches destructively. Non-option arguments # remain in `argv`. @@ -815,11 +831,11 @@ class OptionParser # --> # Directs to reject specified class argument. # - # `t` + # `type` # : Argument class specifier, any object including Class. # # - # reject(t) + # reject(type) # def reject: (Class t) -> void @@ -954,6 +970,13 @@ class OptionParser # rdoc-file=lib/optparse.rb # - warn(mesg = $!) # --> + # Shows warning message with the program name + # + # `mesg` + # : Message, defaulted to +$!+. + # + # + # See Kernel#warn. # def warn: (?_ToS mesg) -> void @@ -1068,6 +1091,9 @@ OptionParser::RequiredArgument: Array[untyped] OptionParser::SPLAT_PROC: Proc +# +# The version string +# OptionParser::Version: String # @@ -1113,7 +1139,7 @@ module OptionParser::Arguable # # Substitution of getopts is possible as follows. Also see OptionParser#getopts. # @@ -1152,7 +1178,7 @@ module OptionParser::Arguable # # Parses `self` destructively in order and returns `self` containing the rest # arguments left unparsed. @@ -1161,7 +1187,7 @@ module OptionParser::Arguable # # Parses `self` destructively and returns `self` containing the rest arguments # left unparsed. @@ -1170,7 +1196,7 @@ module OptionParser::Arguable # # Parses `self` destructively in permutation mode and returns `self` containing # the rest arguments left unparsed. @@ -1691,7 +1717,7 @@ end class OptionParser::Switch::RequiredArgument < OptionParser::Switch # # Raises an exception if argument is not present. # diff --git a/stdlib/pp/0/pp.rbs b/stdlib/pp/0/pp.rbs index a3be023ef0..9ed9cec7fb 100644 --- a/stdlib/pp/0/pp.rbs +++ b/stdlib/pp/0/pp.rbs @@ -72,6 +72,9 @@ class PP < PrettyPrint def group: (?Integer indent, ?String open_obj, ?String close_obj, ?Integer open_width, ?Integer close_width) { () -> untyped } -> void end + # + # Module that defines helper methods for pretty_print. + # module PPMethods : _PPMethodsRequired # # Loads the document contained in `filename`. Returns the yaml contained in # `filename` as a Ruby object, or if the file is empty, it returns the specified - # `fallback` return value, which defaults to `false`. See load for options. + # `fallback` return value, which defaults to `nil`. See load for options. # %a{annotate:rdoc:copy:Psych.load_file} def self.load_file: (string | _ToPath, ?fallback: untyped, ?symbolize_names: bool, ?freeze: bool) -> untyped diff --git a/stdlib/pty/0/pty.rbs b/stdlib/pty/0/pty.rbs index 9f01a6c63c..809ec3fd67 100644 --- a/stdlib/pty/0/pty.rbs +++ b/stdlib/pty/0/pty.rbs @@ -86,9 +86,17 @@ module PTY # the spawned pty. # # # sets FOO to "bar" - # PTY.spawn({"FOO"=>"bar"}, "printenv", "FOO") { |r,w,pid| p r.read } #=> "bar\r\n" + # PTY.spawn({"FOO"=>"bar"}, "printenv", "FOO") do |r, w, pid| + # p r.read #=> "bar\r\n" + # ensure + # r.close; w.close; Process.wait(pid) + # end # # unsets FOO - # PTY.spawn({"FOO"=>nil}, "printenv", "FOO") { |r,w,pid| p r.read } #=> "" + # PTY.spawn({"FOO"=>nil}, "printenv", "FOO") do |r, w, pid| + # p r.read #=> "" + # ensure + # r.close; w.close; Process.wait(pid) + # end # # `command` and `command_line` are the full commands to run, given a String. Any # additional `arguments` will be passed to the command. @@ -109,6 +117,16 @@ module PTY # `pid` # : The process identifier for the command. # + # + # ### Clean up + # + # This method does not clean up like closing IOs or waiting for child process, + # except that the process is detached in the block form to prevent it from + # becoming a zombie (see Process.detach). Any other cleanup is the + # responsibility of the caller. If waiting for `pid`, be sure to close both `r` + # and `w` before doing so; doing it in the reverse order may cause deadlock on + # some OSes. + # alias self.getpty self.spawn # # creates a new socket object connected to host:port using TCP/IP. # + # Starting from Ruby 3.4, this method operates according to the Happy Eyeballs + # Version 2 ([RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305)) + # algorithm by default. + # + # To make it behave the same as in Ruby 3.3 and earlier, explicitly specify the + # option `fast_fallback:false`. + # # If local_host:local_port is given, the socket is bound to it. # # The optional last argument *opts* is options represented by a hash. *opts* may # have following options: # + # :resolv_timeout + # : Specifies the timeout in seconds from when the hostname resolution starts. + # # :connect_timeout - # : specify the timeout in seconds. + # : This method sequentially attempts connecting to all candidate destination + # addresses. + # The `connect_timeout` specifies the timeout in seconds from the start of + # the connection attempt to the last candidate. + # By default, all connection attempts continue until the timeout occurs. + # When `fast_fallback:false` is explicitly specified, + # a timeout is set for each connection attempt and any connection attempt + # that exceeds its timeout will be canceled. + # + # :fast_fallback + # : Enables the Happy Eyeballs Version 2 algorithm (enabled by default). # # # If a block is given, the block is called with the socket. The value of the @@ -478,6 +498,31 @@ class Socket < BasicSocket # puts sock.read # } # + # ### Happy Eyeballs Version 2 + # Happy Eyeballs Version 2 ([RFC + # 8305](https://datatracker.ietf.org/doc/html/rfc8305)) is an algorithm designed + # to improve client socket connectivity. + # It aims for more reliable and efficient connections by performing hostname + # resolution and connection attempts in parallel, instead of serially. + # + # Starting from Ruby 3.4, this method operates as follows with this algorithm: + # + # 1. Start resolving both IPv6 and IPv4 addresses concurrently. + # 2. Start connecting to the one of the addresses that are obtained first. + # If IPv4 addresses are obtained first, the method waits 50 ms for IPv6 name + # resolution to prioritize IPv6 connections. + # 3. After starting a connection attempt, wait 250 ms for the connection to be + # established. + # If no connection is established within this time, a new connection is + # started every 250 ms + # until a connection is established or there are no more candidate + # addresses. + # (Although RFC 8305 strictly specifies sorting addresses, + # this method only alternates between IPv6 / IPv4 addresses due to the + # performance concerns) + # 4. Once a connection is established, all remaining connection attempts are + # canceled. + # def self.tcp: (String host, Integer port, ?String local_host, ?Integer local_port, ?resolv_timeout: Time::_Timeout, ?connect_timeout: Time::_Timeout) -> instance | (String host, Integer port, ?String local_host, ?Integer local_port, ?resolv_timeout: Time::_Timeout, ?connect_timeout: Time::_Timeout) { (instance) -> void } -> void diff --git a/stdlib/socket/0/tcp_socket.rbs b/stdlib/socket/0/tcp_socket.rbs index 369df1c6b1..39089c4fd3 100644 --- a/stdlib/socket/0/tcp_socket.rbs +++ b/stdlib/socket/0/tcp_socket.rbs @@ -37,9 +37,65 @@ class TCPSocket < IPSocket private # + # Opens a TCP connection to `remote_host` on `remote_port`. If `local_host` and + # `local_port` are specified, then those parameters are used on the local end to + # establish the connection. + # + # Starting from Ruby 3.4, this method operates according to the Happy Eyeballs + # Version 2 ([RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305)) + # algorithm by default, except on Windows. + # + # To make it behave the same as in Ruby 3.3 and earlier, explicitly specify the + # option `fast_fallback:false`. + # + # Happy Eyeballs Version 2 is not provided on Windows, and it behaves the same + # as in Ruby 3.3 and earlier. + # + # :resolv_timeout + # : Specifies the timeout in seconds from when the hostname resolution starts. + # + # :connect_timeout + # : This method sequentially attempts connecting to all candidate destination + # addresses. + # The `connect_timeout` specifies the timeout in seconds from the start of + # the connection attempt to the last candidate. + # By default, all connection attempts continue until the timeout occurs. + # When `fast_fallback:false` is explicitly specified, + # a timeout is set for each connection attempt and any connection attempt + # that exceeds its timeout will be canceled. + # + # :fast_fallback + # : Enables the Happy Eyeballs Version 2 algorithm (enabled by default). + # + # + # ### Happy Eyeballs Version 2 + # Happy Eyeballs Version 2 ([RFC + # 8305](https://datatracker.ietf.org/doc/html/rfc8305)) is an algorithm designed + # to improve client socket connectivity. + # It aims for more reliable and efficient connections by performing hostname + # resolution and connection attempts in parallel, instead of serially. + # + # Starting from Ruby 3.4, this method operates as follows with this algorithm + # except on Windows: + # + # 1. Start resolving both IPv6 and IPv4 addresses concurrently. + # 2. Start connecting to the one of the addresses that are obtained first. + # If IPv4 addresses are obtained first, the method waits 50 ms for IPv6 name + # resolution to prioritize IPv6 connections. + # 3. After starting a connection attempt, wait 250 ms for the connection to be + # established. + # If no connection is established within this time, a new connection is + # started every 250 ms + # until a connection is established or there are no more candidate + # addresses. + # (Although RFC 8305 strictly specifies sorting addresses, + # this method only alternates between IPv6 / IPv4 addresses due to the + # performance concerns) + # 4. Once a connection is established, all remaining connection attempts are + # canceled. # def initialize: (String remote_host, Integer remote_port, ?String local_host, ?Integer local_port) -> untyped end diff --git a/stdlib/strscan/0/string_scanner.rbs b/stdlib/strscan/0/string_scanner.rbs index 321ce53140..9087428f63 100644 --- a/stdlib/strscan/0/string_scanner.rbs +++ b/stdlib/strscan/0/string_scanner.rbs @@ -1,102 +1,426 @@ # -# StringScanner provides for lexical scanning operations on a String. Here is -# an example of its usage: -# +# Class `StringScanner` supports processing a stored string as a stream; +# this code creates a new `StringScanner` object with string `'foobarbaz'`: # require 'strscan' +# scanner = StringScanner.new('foobarbaz') # -# s = StringScanner.new('This is an example string') -# s.eos? # -> false -# -# p s.scan(/\w+/) # -> "This" -# p s.scan(/\w+/) # -> nil -# p s.scan(/\s+/) # -> " " -# p s.scan(/\s+/) # -> nil -# p s.scan(/\w+/) # -> "is" -# s.eos? # -> false -# -# p s.scan(/\s+/) # -> " " -# p s.scan(/\w+/) # -> "an" -# p s.scan(/\s+/) # -> " " -# p s.scan(/\w+/) # -> "example" -# p s.scan(/\s+/) # -> " " -# p s.scan(/\w+/) # -> "string" -# s.eos? # -> true -# -# p s.scan(/\s+/) # -> nil -# p s.scan(/\w+/) # -> nil +# ## About the Examples +# All examples here assume that `StringScanner` has been required: +# require 'strscan' # -# Scanning a string means remembering the position of a *scan pointer*, which is -# just an index. The point of scanning is to move forward a bit at a time, so -# matches are sought after the scan pointer; usually immediately after it. +# Some examples here assume that these constants are defined: +# MULTILINE_TEXT = <<~EOT +# Go placidly amid the noise and haste, +# and remember what peace there may be in silence. +# EOT # -# Given the string "test string", here are the pertinent scan pointer positions: +# HIRAGANA_TEXT = 'こんにちは' # -# t e s t s t r i n g -# 0 1 2 ... 1 -# 0 +# ENGLISH_TEXT = 'Hello' # -# When you #scan for a pattern (a regular expression), the match must occur at -# the character after the scan pointer. If you use #scan_until, then the match -# can occur anywhere after the scan pointer. In both cases, the scan pointer -# moves *just beyond* the last character of the match, ready to scan again from -# the next character onwards. This is demonstrated by the example above. +# Some examples here assume that certain helper methods are defined: +# * `put_situation(scanner)`: +# Displays the values of the scanner's +# methods #pos, #charpos, #rest, and #rest_size. +# * `put_match_values(scanner)`: +# Displays the scanner's [match +# values](rdoc-ref:StringScanner@Match+Values). +# * `match_values_cleared?(scanner)`: +# Returns whether the scanner's [match +# values](rdoc-ref:StringScanner@Match+Values) are cleared. +# See examples [[here]](ext/strscan/helper_methods_md.html). +# ## The `StringScanner` Object +# This code creates a `StringScanner` object +# (we'll call it simply a *scanner*), +# and shows some of its basic properties: +# scanner = StringScanner.new('foobarbaz') +# scanner.string # => "foobarbaz" +# put_situation(scanner) +# # Situation: +# # pos: 0 +# # charpos: 0 +# # rest: "foobarbaz" +# # rest_size: 9 # -# ## Method Categories +# The scanner has: +# * A *stored string*, which is: +# * Initially set by StringScanner.new(string) to the given `string` +# (`'foobarbaz'` in the example above). +# * Modifiable by methods #string=(new_string) and #concat(more_string). +# * Returned by method #string. +# More at [Stored String](rdoc-ref:StringScanner@Stored+String) below. +# * A *position*; +# a zero-based index into the bytes of the stored string (*not* into its +# characters): +# * Initially set by StringScanner.new to `0`. +# * Returned by method #pos. +# * Modifiable explicitly by methods #reset, #terminate, and +# #pos=(new_pos). +# * Modifiable implicitly (various traversing methods, among others). +# More at [Byte +# Position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) below. +# * A *target substring*, +# which is a trailing substring of the stored string; +# it extends from the current position to the end of the stored string: +# * Initially set by StringScanner.new(string) to the given `string` +# (`'foobarbaz'` in the example above). +# * Returned by method #rest. +# * Modified by any modification to either the stored string or the +# position. +# **Most importantly**: +# the searching and traversing methods operate on the target substring, +# which may be (and often is) less than the entire stored string. +# More at [Target Substring](rdoc-ref:StringScanner@Target+Substring) below. +# ## Stored String +# The *stored string* is the string stored in the `StringScanner` object. +# Each of these methods sets, modifies, or returns the stored string: +# Method | Effect +# --------------------|----------------------------------------------- +# ::new(string) | Creates a new scanner for the given string. +# #string=(new_string)| Replaces the existing stored string. +# #concat(more_string)|Appends a string to the existing stored string. +# #string | Returns the stored string. +# ## Positions +# A `StringScanner` object maintains a zero-based *byte position* +# and a zero-based *character position*. +# Each of these methods explicitly sets positions: +# Method | Effect +# ------------------------|-------------------------------------------------------- +# #reset |Sets both positions to zero (begining of stored string). +# #terminate | Sets both positions to the end of the stored string. +# #pos=(new_byte_position)| Sets byte position; adjusts character position. +# ### Byte Position (Position) +# The byte position (or simply *position*) +# is a zero-based index into the bytes in the scanner's stored string; +# for a new `StringScanner` object, the byte position is zero. +# When the byte position is: +# * Zero (at the beginning), the target substring is the entire stored string. +# * Equal to the size of the stored string (at the end), +# the target substring is the empty string `''`. +# To get or set the byte position: +# * #pos: returns the byte position. +# * #pos=(new_pos): sets the byte position. +# Many methods use the byte position as the basis for finding matches; +# many others set, increment, or decrement the byte position: +# scanner = StringScanner.new('foobar') +# scanner.pos # => 0 +# scanner.scan(/foo/) # => "foo" # Match found. +# scanner.pos # => 3 # Byte position incremented. +# scanner.scan(/foo/) # => nil # Match not found. +# scanner.pos # => 3 # Byte position not changed. # -# There are other methods besides the plain scanners. You can look ahead in the -# string without actually scanning. You can access the most recent match. You -# can modify the string being scanned, reset or terminate the scanner, find out -# or change the position of the scan pointer, skip ahead, and so on. +# Some methods implicitly modify the byte position; +# see: +# * [Setting the Target +# Substring](rdoc-ref:StringScanner@Setting+the+Target+Substring). +# * [Traversing the Target +# Substring](rdoc-ref:StringScanner@Traversing+the+Target+Substring). +# The values of these methods are derived directly from the values of #pos and +# #string: +# * #charpos: the [character +# position](rdoc-ref:StringScanner@Character+Position). +# * #rest: the [target substring](rdoc-ref:StringScanner@Target+Substring). +# * #rest_size: `rest.size`. +# ### Character Position +# The character position is a zero-based index into the *characters* +# in the stored string; +# for a new `StringScanner` object, the character position is zero. +# Method #charpos returns the character position; +# its value may not be reset explicitly. +# Some methods change (increment or reset) the character position; +# see: +# * [Setting the Target +# Substring](rdoc-ref:StringScanner@Setting+the+Target+Substring). +# * [Traversing the Target +# Substring](rdoc-ref:StringScanner@Traversing+the+Target+Substring). +# Example (string includes multi-byte characters): +# scanner = StringScanner.new(ENGLISH_TEXT) # Five 1-byte characters. +# scanner.concat(HIRAGANA_TEXT) # Five 3-byte characters +# scanner.string # => "Helloこんにちは" # Twenty bytes in all. +# put_situation(scanner) +# # Situation: +# # pos: 0 +# # charpos: 0 +# # rest: "Helloこんにちは" +# # rest_size: 20 +# scanner.scan(/Hello/) # => "Hello" # Five 1-byte characters. +# put_situation(scanner) +# # Situation: +# # pos: 5 +# # charpos: 5 +# # rest: "こんにちは" +# # rest_size: 15 +# scanner.getch # => "こ" # One 3-byte character. +# put_situation(scanner) +# # Situation: +# # pos: 8 +# # charpos: 6 +# # rest: "んにちは" +# # rest_size: 12 # -# ### Advancing the Scan Pointer +# ## Target Substring +# The target substring is the the part of the [stored +# string](rdoc-ref:StringScanner@Stored+String) +# that extends from the current [byte +# position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to the end of +# the stored string; +# it is always either: +# * The entire stored string (byte position is zero). +# * A trailing substring of the stored string (byte position positive). +# The target substring is returned by method #rest, +# and its size is returned by method #rest_size. +# Examples: +# scanner = StringScanner.new('foobarbaz') +# put_situation(scanner) +# # Situation: +# # pos: 0 +# # charpos: 0 +# # rest: "foobarbaz" +# # rest_size: 9 +# scanner.pos = 3 +# put_situation(scanner) +# # Situation: +# # pos: 3 +# # charpos: 3 +# # rest: "barbaz" +# # rest_size: 6 +# scanner.pos = 9 +# put_situation(scanner) +# # Situation: +# # pos: 9 +# # charpos: 9 +# # rest: "" +# # rest_size: 0 # -# * #getch -# * #get_byte -# * #scan -# * #scan_until -# * #skip -# * #skip_until +# ### Setting the Target Substring +# The target substring is set whenever: +# * The [stored string](rdoc-ref:StringScanner@Stored+String) is set (position +# reset to zero; target substring set to stored string). +# * The [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) +# is set (target substring adjusted accordingly). +# ### Querying the Target Substring +# This table summarizes (details and examples at the links): +# Method | Returns +# ----------|--------------------------------- +# #rest | Target substring. +# #rest_size|Size (bytes) of target substring. +# ### Searching the Target Substring +# A *search* method examines the target substring, +# but does not advance the [positions](rdoc-ref:StringScanner@Positions) +# or (by implication) shorten the target substring. +# This table summarizes (details and examples at the links): +# Method | Returns |Sets Match Values? +# ---------------------|---------------------------------------------|------------------ +# #check(pattern) | Matched leading substring or +nil+. | Yes. +# #check_until(pattern)| Matched substring (anywhere) or +nil+. | Yes. +# #exist?(pattern) | Matched substring (anywhere) end index. | Yes. +# #match?(pattern) | Size of matched leading substring or +nil+. | Yes. +# #peek(size) | Leading substring of given length (bytes). | No. +# #peek_byte | Integer leading byte or +nil+. | No. +# #rest |Target substring (from byte position to end).| No. +# ### Traversing the Target Substring +# A *traversal* method examines the target substring, +# and, if successful: +# * Advances the [positions](rdoc-ref:StringScanner@Positions). +# * Shortens the target substring. +# This table summarizes (details and examples at links): +# Method | Returns |Sets Match Values? +# --------------------|----------------------------------------------------|------------------ +# #get_byte | Leading byte or +nil+. | No. +# #getch | Leading character or +nil+. | No. +# #scan(pattern) | Matched leading substring or +nil+. | Yes. +# #scan_byte | Integer leading byte or +nil+. | No. +# #scan_until(pattern)| Matched substring (anywhere) or +nil+. | Yes. +# #skip(pattern) | Matched leading substring size or +nil+. | Yes. +# #skip_until(pattern)|Position delta to end-of-matched-substring or +nil+.| Yes. +# #unscan | +self+. | No. +# ## Querying the Scanner +# Each of these methods queries the scanner object +# without modifying it (details and examples at links) +# Method | Returns +# -------------------|-------------------------------- +# #beginning_of_line?| +true+ or +false+. +# #charpos | Character position. +# #eos? | +true+ or +false+. +# #fixed_anchor? | +true+ or +false+. +# #inspect |String representation of +self+. +# #pos | Byte position. +# #rest | Target substring. +# #rest_size | Size of target substring. +# #string | Stored string. +# ## Matching +# `StringScanner` implements pattern matching via Ruby class +# [Regexp](https://docs.ruby-lang.org/en/master/Regexp.html), +# and its matching behaviors are the same as Ruby's +# except for the [fixed-anchor +# property](rdoc-ref:StringScanner@Fixed-Anchor+Property). +# ### Matcher Methods +# Each *matcher method* takes a single argument `pattern`, +# and attempts to find a matching substring in the [target +# substring](rdoc-ref:StringScanner@Target+Substring). +# Method | Pattern Type |Matches Target Substring| Success Return |May Update Positions? +# ------------|-----------------|------------------------|------------------|--------------------- +# #check |Regexp or String.| At beginning. |Matched substring.| No. +# #check_until|Regexp or String.| Anywhere. | Substring. | No. +# #match? |Regexp or String.| At beginning. | Match size. | No. +# #exist? |Regexp or String.| Anywhere. | Substring size. | No. +# #scan |Regexp or String.| At beginning. |Matched substring.| Yes. +# #scan_until |Regexp or String.| Anywhere. | Substring. | Yes. +# #skip |Regexp or String.| At beginning. | Match size. | Yes. +# #skip_until |Regexp or String.| Anywhere. | Substring size. | Yes. # -# ### Looking Ahead +# Which matcher you choose will depend on: +# * Where you want to find a match: +# * Only at the beginning of the target substring: +# #check, #match?, #scan, #skip. +# * Anywhere in the target substring: +# #check_until, #exist?, #scan_until, #skip_until. +# * Whether you want to: +# * Traverse, by advancing the positions: +# #scan, #scan_until, #skip, #skip_until. +# * Keep the positions unchanged: +# #check, #check_until, #match?, #exist?. +# * What you want for the return value: +# * The matched substring: #check, #scan. +# * The substring: #check_until, #scan_until. +# * The match size: #match?, #skip. +# * The substring size: #exist?, #skip_until. +# ### Match Values +# The *match values* in a `StringScanner` object +# generally contain the results of the most recent attempted match. +# Each match value may be thought of as: +# * *Clear*: Initially, or after an unsuccessful match attempt: +# usually, `false`, `nil`, or `{}`. +# * *Set*: After a successful match attempt: +# `true`, string, array, or hash. +# Each of these methods clears match values: +# * ::new(string). +# * #reset. +# * #terminate. +# Each of these methods attempts a match based on a pattern, +# and either sets match values (if successful) or clears them (if not); +# * #check(pattern) +# * #check_until(pattern) +# * #exist?(pattern) +# * #match?(pattern) +# * #scan(pattern) +# * #scan_until(pattern) +# * #skip(pattern) +# * #skip_until(pattern) +# #### Basic Match Values +# Basic match values are those not related to captures. +# Each of these methods returns a basic match value: +# Method | Return After Match |Return After No Match +# -------------|--------------------------------------|--------------------- +# #matched? | +true+. | +false+. +# #matched_size| Size of matched substring. | +nil+. +# #matched | Matched substring. | +nil+. +# #pre_match |Substring preceding matched substring.| +nil+. +# #post_match |Substring following matched substring.| +nil+. # -# * #check -# * #check_until -# * #exist? -# * #match? -# * #peek +# See examples below. +# #### Captured Match Values +# Captured match values are those related to +# [captures](https://docs.ruby-lang.org/en/master/Regexp.html#class-Regexp-label +# -Groups+and+Captures). +# Each of these methods returns a captured match value: +# Method | Return After Match |Return After No Match +# ---------------|---------------------------------------|--------------------- +# #size | Count of captured substrings. | +nil+. +# #[](n) | nth captured substring. | +nil+. +# #captures | Array of all captured substrings. | +nil+. +# #values_at(*n) |Array of specified captured substrings.| +nil+. +# #named_captures| Hash of named captures. | {}. # -# ### Finding Where we Are +# See examples below. +# #### Match Values Examples +# Successful basic match attempt (no captures): +# scanner = StringScanner.new('foobarbaz') +# scanner.exist?(/bar/) +# put_match_values(scanner) +# # Basic match values: +# # matched?: true +# # matched_size: 3 +# # pre_match: "foo" +# # matched : "bar" +# # post_match: "baz" +# # Captured match values: +# # size: 1 +# # captures: [] +# # named_captures: {} +# # values_at: ["bar", nil] +# # []: +# # [0]: "bar" +# # [1]: nil # -# * #beginning_of_line? (`#bol?`) -# * #eos? -# * #rest? -# * #rest_size -# * #pos +# Failed basic match attempt (no captures); +# scanner = StringScanner.new('foobarbaz') +# scanner.exist?(/nope/) +# match_values_cleared?(scanner) # => true # -# ### Setting Where we Are +# Successful unnamed capture match attempt: +# scanner = StringScanner.new('foobarbazbatbam') +# scanner.exist?(/(foo)bar(baz)bat(bam)/) +# put_match_values(scanner) +# # Basic match values: +# # matched?: true +# # matched_size: 15 +# # pre_match: "" +# # matched : "foobarbazbatbam" +# # post_match: "" +# # Captured match values: +# # size: 4 +# # captures: ["foo", "baz", "bam"] +# # named_captures: {} +# # values_at: ["foobarbazbatbam", "foo", "baz", "bam", nil] +# # []: +# # [0]: "foobarbazbatbam" +# # [1]: "foo" +# # [2]: "baz" +# # [3]: "bam" +# # [4]: nil # -# * #reset -# * #terminate -# * #pos= +# Successful named capture match attempt; +# same as unnamed above, except for #named_captures: +# scanner = StringScanner.new('foobarbazbatbam') +# scanner.exist?(/(?foo)bar(?baz)bat(?bam)/) +# scanner.named_captures # => {"x"=>"foo", "y"=>"baz", "z"=>"bam"} # -# ### Match Data +# Failed unnamed capture match attempt: +# scanner = StringScanner.new('somestring') +# scanner.exist?(/(foo)bar(baz)bat(bam)/) +# match_values_cleared?(scanner) # => true # -# * #matched -# * #matched? -# * #matched_size -# * `#[]` -# * #pre_match -# * #post_match +# Failed named capture match attempt; +# same as unnamed above, except for #named_captures: +# scanner = StringScanner.new('somestring') +# scanner.exist?(/(?foo)bar(?baz)bat(?bam)/) +# match_values_cleared?(scanner) # => false +# scanner.named_captures # => {"x"=>nil, "y"=>nil, "z"=>nil} # -# ### Miscellaneous +# ## Fixed-Anchor Property +# Pattern matching in `StringScanner` is the same as in Ruby's, +# except for its fixed-anchor property, +# which determines the meaning of `'\A'`: +# * `false` (the default): matches the current byte position. +# scanner = StringScanner.new('foobar') +# scanner.scan(/\A./) # => "f" +# scanner.scan(/\A./) # => "o" +# scanner.scan(/\A./) # => "o" +# scanner.scan(/\A./) # => "b" # -# * `<<` -# * #concat -# * #string -# * #string= -# * #unscan +# * `true`: matches the beginning of the target substring; +# never matches unless the byte position is zero: +# scanner = StringScanner.new('foobar', fixed_anchor: true) +# scanner.scan(/\A./) # => "f" +# scanner.scan(/\A./) # => nil +# scanner.reset +# scanner.scan(/\A./) # => "f" # -# There are aliases to several of the methods. +# The fixed-anchor property is set when the `StringScanner` object is created, +# and may not be modified +# (see StringScanner.new); +# method #fixed_anchor? returns the setting. # class StringScanner # - # Appends `str` to the string being scanned. This method does not affect scan - # pointer. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/Fri /) - # s << " +1000 GMT" - # s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT" - # s.scan(/Dec/) # -> "Dec" + # * Appends the given `more_string` + # to the [stored string](rdoc-ref:StringScanner@Stored+String). + # * Returns `self`. + # * Does not affect the [positions](rdoc-ref:StringScanner@Positions) + # or [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new('foo') + # scanner.string # => "foo" + # scanner.terminate + # scanner.concat('barbaz') # => # + # scanner.string # => "foobarbaz" + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "barbaz" + # # rest_size: 6 # def <<: (String) -> self # - # Returns the n-th subgroup in the most recent match. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - # s[0] # -> "Fri Dec 12 " - # s[1] # -> "Fri" - # s[2] # -> "Dec" - # s[3] # -> "12" - # s.post_match # -> "1975 14:39" - # s.pre_match # -> "" - # - # s.reset - # s.scan(/(?\w+) (?\w+) (?\d+) /) # -> "Fri Dec 12 " - # s[0] # -> "Fri Dec 12 " - # s[1] # -> "Fri" - # s[2] # -> "Dec" - # s[3] # -> "12" - # s[:wday] # -> "Fri" - # s[:month] # -> "Dec" - # s[:day] # -> "12" - # s.post_match # -> "1975 14:39" - # s.pre_match # -> "" + # Returns a captured substring or `nil`; + # see [Captured Match Values](rdoc-ref:StringScanner@Captured+Match+Values). + # When there are captures: + # scanner = StringScanner.new('Fri Dec 12 1975 14:39') + # scanner.scan(/(?\w+) (?\w+) (?\d+) /) + # + # * `specifier` zero: returns the entire matched substring: + # scanner[0] # => "Fri Dec 12 " + # scanner.pre_match # => "" + # scanner.post_match # => "1975 14:39" + # + # * `specifier` positive integer. returns the `n`th capture, or `nil` if out + # of range: + # scanner[1] # => "Fri" + # scanner[2] # => "Dec" + # scanner[3] # => "12" + # scanner[4] # => nil + # + # * `specifier` negative integer. counts backward from the last subgroup: + # scanner[-1] # => "12" + # scanner[-4] # => "Fri Dec 12 " + # scanner[-5] # => nil + # + # * `specifier` symbol or string. returns the named subgroup, or `nil` if no + # such: + # scanner[:wday] # => "Fri" + # scanner['wday'] # => "Fri" + # scanner[:month] # => "Dec" + # scanner[:day] # => "12" + # scanner[:nope] # => nil + # + # When there are no captures, only `[0]` returns non-`nil`: + # scanner = StringScanner.new('foobarbaz') + # scanner.exist?(/bar/) + # scanner[0] # => "bar" + # scanner[1] # => nil + # + # For a failed match, even `[0]` returns `nil`: + # scanner.scan(/nope/) # => nil + # scanner[0] # => nil + # scanner[1] # => nil # def []: (Integer) -> String? # - # Returns `true` if and only if the scan pointer is at the beginning of the - # line. + # Returns whether the + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is at the + # beginning of a line; + # that is, at the beginning of the [stored + # string](rdoc-ref:StringScanner@Stored+String) + # or immediately after a newline: + # scanner = StringScanner.new(MULTILINE_TEXT) + # scanner.string + # # => "Go placidly amid the noise and haste,\nand remember what peace there may be in silence.\n" + # scanner.pos # => 0 + # scanner.beginning_of_line? # => true + # + # scanner.scan_until(/,/) # => "Go placidly amid the noise and haste," + # scanner.beginning_of_line? # => false # - # s = StringScanner.new("test\ntest\n") - # s.bol? # => true - # s.scan(/te/) - # s.bol? # => false - # s.scan(/st\n/) - # s.bol? # => true - # s.terminate - # s.bol? # => true + # scanner.scan(/\n/) # => "\n" + # scanner.beginning_of_line? # => true + # + # scanner.terminate + # scanner.beginning_of_line? # => true + # + # scanner.concat('x') + # scanner.terminate + # scanner.beginning_of_line? # => false + # + # StringScanner#bol? is an alias for StringScanner#beginning_of_line?. # def beginning_of_line?: () -> bool @@ -170,16 +536,23 @@ class StringScanner # - # Returns the subgroups in the most recent match (not including the full match). - # If nothing was priorly matched, it returns nil. + # Returns the array of [captured match + # values](rdoc-ref:StringScanner@Captured+Match+Values) at indexes `(1..)` + # if the most recent match attempt succeeded, or `nil` otherwise: + # scanner = StringScanner.new('Fri Dec 12 1975 14:39') + # scanner.captures # => nil + # + # scanner.exist?(/(?\w+) (?\w+) (?\d+) /) + # scanner.captures # => ["Fri", "Dec", "12"] + # scanner.values_at(*0..4) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil] + # + # scanner.exist?(/Fri/) + # scanner.captures # => [] # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> "Fri Dec 12 " - # s.captures # -> ["Fri", "Dec", "12", nil] - # s.scan(/(\w+) (\w+) (\d+) (1980)?/) # -> nil - # s.captures # -> nil + # scanner.scan(/nope/) + # scanner.captures # => nil # def captures: () -> Array[String]? @@ -187,51 +560,116 @@ class StringScanner # rdoc-file=ext/strscan/strscan.c # - charpos() # --> - # Returns the character position of the scan pointer. In the 'reset' position, - # this value is zero. In the 'terminated' position (i.e. the string is - # exhausted), this value is the size of the string. - # - # In short, it's a 0-based index into the string. - # - # s = StringScanner.new("abc\u00e4def\u00f6ghi") - # s.charpos # -> 0 - # s.scan_until(/\u00e4/) # -> "abc\u00E4" - # s.pos # -> 5 - # s.charpos # -> 4 + # call-seq: + # charpos -> character_position + # Returns the [character position](rdoc-ref:StringScanner@Character+Position) + # (initially zero), + # which may be different from the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # given by method #pos: + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.getch # => "こ" # 3-byte character. + # scanner.getch # => "ん" # 3-byte character. + # put_situation(scanner) + # # Situation: + # # pos: 6 + # # charpos: 2 + # # rest: "にちは" + # # rest_size: 9 # def charpos: () -> Integer # - # This returns the value that #scan would return, without advancing the scan - # pointer. The match register is affected, though. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.check /Fri/ # -> "Fri" - # s.pos # -> 0 - # s.matched # -> "Fri" - # s.check /12/ # -> nil - # s.matched # -> nil - # - # Mnemonic: it "checks" to see whether a #scan will return a value. + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # at the beginning of the [target + # substring](rdoc-ref:StringScanner@Target+Substring); + # does not modify the [positions](rdoc-ref:StringScanner@Positions). + # If the match succeeds: + # * Returns the matched substring. + # * Sets all [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new('foobarbaz') + # scanner.pos = 3 + # scanner.check('bar') # => "bar" + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "foo" + # # matched : "bar" + # # post_match: "baz" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["bar", nil] + # # []: + # # [0]: "bar" + # # [1]: nil + # # => 0..1 + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "barbaz" + # # rest_size: 6 + # + # If the match fails: + # * Returns `nil`. + # * Clears all [match values](rdoc-ref:StringScanner@Match+Values). + # scanner.check(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def check: (Regexp) -> String? # - # This returns the value that #scan_until would return, without advancing the - # scan pointer. The match register is affected, though. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.check_until /12/ # -> "Fri Dec 12" - # s.pos # -> 0 - # s.matched # -> 12 - # - # Mnemonic: it "checks" to see whether a #scan_until will return a value. + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # anywhere (at any + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) + # in the [target substring](rdoc-ref:StringScanner@Target+Substring); + # does not modify the [positions](rdoc-ref:StringScanner@Positions). + # If the match succeeds: + # * Sets all [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns the matched substring, + # which extends from the current + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # to the end of the matched substring. + # scanner = StringScanner.new('foobarbazbatbam') + # scanner.pos = 6 + # scanner.check_until(/bat/) # => "bazbat" + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "foobarbaz" + # # matched : "bat" + # # post_match: "bam" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["bat", nil] + # # []: + # # [0]: "bat" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 6 + # # charpos: 6 + # # rest: "bazbatbam" + # # rest_size: 9 + # + # If the match fails: + # * Clears all [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns `nil`. + # scanner.check_until(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def check_until: (Regexp) -> String @@ -245,17 +683,24 @@ class StringScanner # - # Appends `str` to the string being scanned. This method does not affect scan - # pointer. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/Fri /) - # s << " +1000 GMT" - # s.string # -> "Fri Dec 12 1975 14:39 +1000 GMT" - # s.scan(/Dec/) # -> "Dec" + # * Appends the given `more_string` + # to the [stored string](rdoc-ref:StringScanner@Stored+String). + # * Returns `self`. + # * Does not affect the [positions](rdoc-ref:StringScanner@Positions) + # or [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new('foo') + # scanner.string # => "foo" + # scanner.terminate + # scanner.concat('barbaz') # => # + # scanner.string # => "foobarbaz" + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "barbaz" + # # rest_size: 6 # alias concat << @@ -269,43 +714,74 @@ class StringScanner # - # Returns `true` if the scan pointer is at the end of the string. - # - # s = StringScanner.new('test string') - # p s.eos? # => false - # s.scan(/test/) - # p s.eos? # => false - # s.terminate - # p s.eos? # => true + # Returns whether the + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # is at the end of the [stored string](rdoc-ref:StringScanner@Stored+String): + # scanner = StringScanner.new('foobarbaz') + # scanner.eos? # => false + # pos = 3 + # scanner.eos? # => false + # scanner.terminate + # scanner.eos? # => true # def eos?: () -> bool # - # Looks *ahead* to see if the `pattern` exists *anywhere* in the string, without - # advancing the scan pointer. This predicates whether a #scan_until will return - # a value. - # - # s = StringScanner.new('test string') - # s.exist? /s/ # -> 3 - # s.scan /test/ # -> "test" - # s.exist? /s/ # -> 2 - # s.exist? /e/ # -> nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # anywhere (at any + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) + # n the [target substring](rdoc-ref:StringScanner@Target+Substring); + # does not modify the [positions](rdoc-ref:StringScanner@Positions). + # If the match succeeds: + # * Returns a byte offset: + # the distance in bytes between the current + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # and the end of the matched substring. + # * Sets all [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new('foobarbazbatbam') + # scanner.pos = 6 + # scanner.exist?(/bat/) # => 6 + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "foobarbaz" + # # matched : "bat" + # # post_match: "bam" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["bat", nil] + # # []: + # # [0]: "bat" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 6 + # # charpos: 6 + # # rest: "bazbatbam" + # # rest_size: 9 + # + # If the match fails: + # * Returns `nil`. + # * Clears all [match values](rdoc-ref:StringScanner@Match+Values). + # scanner.exist?(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def exist?: (Regexp) -> Integer? # - # Whether `scanner` uses fixed anchor mode or not. - # - # If fixed anchor mode is used, `\A` always matches the beginning of the string. - # Otherwise, `\A` always matches the current position. + # Returns whether the [fixed-anchor + # property](rdoc-ref:StringScanner@Fixed-Anchor+Property) is set. # def fixed_anchor?: () -> bool @@ -313,18 +789,30 @@ class StringScanner # rdoc-file=ext/strscan/strscan.c # - get_byte() # --> - # Scans one byte and returns it. This method is not multibyte character - # sensitive. See also: #getch. - # - # s = StringScanner.new('ab') - # s.get_byte # => "a" - # s.get_byte # => "b" - # s.get_byte # => nil - # - # s = StringScanner.new("\244\242".force_encoding("euc-jp")) - # s.get_byte # => "\xA4" - # s.get_byte # => "\xA2" - # s.get_byte # => nil + # call-seq: + # get_byte -> byte_as_character or nil + # Returns the next byte, if available: + # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # is not at the end of the [stored + # string](rdoc-ref:StringScanner@Stored+String): + # * Returns the next byte. + # * Increments the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29). + # * Adjusts the [character + # position](rdoc-ref:StringScanner@Character+Position). + # scanner = StringScanner.new(HIRAGANA_TEXT) + # # => # + # scanner.string # => "こんにちは" + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\xE3", 1, 1] + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x81", 2, 2] + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x93", 3, 1] + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\xE3", 4, 2] + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x82", 5, 3] + # [scanner.get_byte, scanner.pos, scanner.charpos] # => ["\x93", 6, 2] + # + # * Otherwise, returns `nil`, and does not change the positions. + # scanner.terminate + # [scanner.get_byte, scanner.pos, scanner.charpos] # => [nil, 15, 5] # def get_byte: () -> String? @@ -340,103 +828,185 @@ class StringScanner # rdoc-file=ext/strscan/strscan.c # - getch() # --> - # Scans one character and returns it. This method is multibyte character - # sensitive. - # - # s = StringScanner.new("ab") - # s.getch # => "a" - # s.getch # => "b" - # s.getch # => nil - # - # s = StringScanner.new("\244\242".force_encoding("euc-jp")) - # s.getch # => "\x{A4A2}" # Japanese hira-kana "A" in EUC-JP - # s.getch # => nil + # call-seq: + # getch -> character or nil + # Returns the next (possibly multibyte) character, + # if available: + # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # is at the beginning of a character: + # * Returns the character. + # * Increments the [character + # position](rdoc-ref:StringScanner@Character+Position) by 1. + # * Increments the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # by the size (in bytes) of the character. + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # [scanner.getch, scanner.pos, scanner.charpos] # => ["こ", 3, 1] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["ん", 6, 2] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["に", 9, 3] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["ち", 12, 4] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["は", 15, 5] + # [scanner.getch, scanner.pos, scanner.charpos] # => [nil, 15, 5] + # + # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is + # within a multi-byte character + # (that is, not at its beginning), + # behaves like #get_byte (returns a 1-byte character): + # scanner.pos = 1 + # [scanner.getch, scanner.pos, scanner.charpos] # => ["\x81", 2, 2] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["\x93", 3, 1] + # [scanner.getch, scanner.pos, scanner.charpos] # => ["ん", 6, 2] + # + # * If the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) is + # at the end of the [stored string](rdoc-ref:StringScanner@Stored+String), + # returns `nil` and does not modify the positions: + # scanner.terminate + # [scanner.getch, scanner.pos, scanner.charpos] # => [nil, 15, 5] # def getch: () -> String? # - # Returns a string that represents the StringScanner object, showing: - # * the current position - # * the size of the string - # * the characters surrounding the scan pointer - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") s.inspect # -> - # '#' s.scan_until /12/ # -> "Fri Dec - # 12" s.inspect # -> '#' + # Returns a string representation of `self` that may show: + # 1. The current + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29). + # 2. The size (in bytes) of the [stored + # string](rdoc-ref:StringScanner@Stored+String). + # 3. The substring preceding the current position. + # 4. The substring following the current position (which is also the [target + # substring](rdoc-ref:StringScanner@Target+Substring)). + # scanner = StringScanner.new("Fri Dec 12 1975 14:39") + # scanner.pos = 11 + # scanner.inspect # => "#" + # + # If at beginning-of-string, item 4 above (following substring) is omitted: + # scanner.reset + # scanner.inspect # => "#" + # + # If at end-of-string, all items above are omitted: + # scanner.terminate + # scanner.inspect # => "#" # def inspect: () -> String # - # Tests whether the given `pattern` is matched from the current scan pointer. - # Returns the length of the match, or `nil`. The scan pointer is not advanced. - # - # s = StringScanner.new('test string') - # p s.match?(/\w+/) # -> 4 - # p s.match?(/\w+/) # -> 4 - # p s.match?("test") # -> 4 - # p s.match?(/\s+/) # -> nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # at the beginning of the [target + # substring](rdoc-ref:StringScanner@Target+Substring); + # does not modify the [positions](rdoc-ref:StringScanner@Positions). + # If the match succeeds: + # * Sets [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns the size in bytes of the matched substring. + # scanner = StringScanner.new('foobarbaz') + # scanner.pos = 3 + # scanner.match?(/bar/) => 3 + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "foo" + # # matched : "bar" + # # post_match: "baz" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["bar", nil] + # # []: + # # [0]: "bar" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "barbaz" + # # rest_size: 6 + # + # If the match fails: + # * Clears match values. + # * Returns `nil`. + # * Does not increment positions. + # scanner.match?(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def match?: (Regexp) -> Integer? # - # Returns the last matched string. - # - # s = StringScanner.new('test string') - # s.match?(/\w+/) # -> 4 - # s.matched # -> "test" + # Returns the matched substring from the most recent + # [match](rdoc-ref:StringScanner@Matching) attempt + # if it was successful, + # or `nil` otherwise; + # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values): + # scanner = StringScanner.new('foobarbaz') + # scanner.matched # => nil + # scanner.pos = 3 + # scanner.match?(/bar/) # => 3 + # scanner.matched # => "bar" + # scanner.match?(/nope/) # => nil + # scanner.matched # => nil # def matched: () -> String? # - # Returns `true` if and only if the last match was successful. - # - # s = StringScanner.new('test string') - # s.match?(/\w+/) # => 4 - # s.matched? # => true - # s.match?(/\d+/) # => nil - # s.matched? # => false + # Returns `true` of the most recent [match + # attempt](rdoc-ref:StringScanner@Matching) was successful, + # `false` otherwise; + # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values): + # scanner = StringScanner.new('foobarbaz') + # scanner.matched? # => false + # scanner.pos = 3 + # scanner.exist?(/baz/) # => 6 + # scanner.matched? # => true + # scanner.exist?(/nope/) # => nil + # scanner.matched? # => false # def matched?: () -> bool # - # Returns the size of the most recent match in bytes, or `nil` if there was no - # recent match. This is different than `matched.size`, which will return the - # size in characters. + # Returns the size (in bytes) of the matched substring + # from the most recent match [match attempt](rdoc-ref:StringScanner@Matching) if + # it was successful, + # or `nil` otherwise; + # see [Basic Matched Values](rdoc-ref:StringScanner@Basic+Match+Values): + # scanner = StringScanner.new('foobarbaz') + # scanner.matched_size # => nil # - # s = StringScanner.new('test string') - # s.check /\w+/ # -> "test" - # s.matched_size # -> 4 - # s.check /\d+/ # -> nil - # s.matched_size # -> nil + # pos = 3 + # scanner.exist?(/baz/) # => 9 + # scanner.matched_size # => 3 + # + # scanner.exist?(/nope/) # => nil + # scanner.matched_size # => nil # def matched_size: () -> Integer? # - # Extracts a string corresponding to `string[pos,len]`, without advancing the - # scan pointer. - # - # s = StringScanner.new('test string') - # s.peek(7) # => "test st" - # s.peek(7) # => "test st" + # Returns the substring `string[pos, length]`; + # does not update [match values](rdoc-ref:StringScanner@Match+Values) or + # [positions](rdoc-ref:StringScanner@Positions): + # scanner = StringScanner.new('foobarbaz') + # scanner.pos = 3 + # scanner.peek(3) # => "bar" + # scanner.terminate + # scanner.peek(3) # => "" # def peek: (Integer) -> String @@ -449,27 +1019,42 @@ class StringScanner def peep: (Integer) -> String # - # Returns the byte position of the scan pointer. In the 'reset' position, this - # value is zero. In the 'terminated' position (i.e. the string is exhausted), - # this value is the bytesize of the string. - # - # In short, it's a 0-based index into bytes of the string. - # - # s = StringScanner.new('test string') - # s.pos # -> 0 - # s.scan_until /str/ # -> "test str" - # s.pos # -> 8 - # s.terminate # -> # - # s.pos # -> 11 + # call-seq: + # pos -> byte_position + # Returns the integer [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29), + # which may be different from the [character + # position](rdoc-ref:StringScanner@Character+Position): + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos # => 0 + # scanner.getch # => "こ" # 3-byte character. + # scanner.charpos # => 1 + # scanner.pos # => 3 # def pointer: () -> Integer # - # Sets the byte position of the scan pointer. - # - # s = StringScanner.new('test string') - # s.pos = 7 # -> 7 - # s.rest # -> "ring" + # call-seq: + # pos = n -> n + # pointer = n -> n + # Sets the [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # and the [character position](rdoc-ref:StringScanner@Positions); + # returns `n`. + # Does not affect [match values](rdoc-ref:StringScanner@Match+Values). + # For non-negative `n`, sets the position to `n`: + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 3 # => 3 + # scanner.rest # => "んにちは" + # scanner.charpos # => 1 + # + # For negative `n`, counts from the end of the [stored + # string](rdoc-ref:StringScanner@Stored+String): + # scanner.pos = -9 # => -9 + # scanner.pos # => 6 + # scanner.rest # => "にちは" + # scanner.charpos # => 2 # def pointer=: (Integer) -> Integer @@ -477,77 +1062,124 @@ class StringScanner # rdoc-file=ext/strscan/strscan.c # - pos() # --> - # Returns the byte position of the scan pointer. In the 'reset' position, this - # value is zero. In the 'terminated' position (i.e. the string is exhausted), - # this value is the bytesize of the string. - # - # In short, it's a 0-based index into bytes of the string. - # - # s = StringScanner.new('test string') - # s.pos # -> 0 - # s.scan_until /str/ # -> "test str" - # s.pos # -> 8 - # s.terminate # -> # - # s.pos # -> 11 + # call-seq: + # pos -> byte_position + # Returns the integer [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29), + # which may be different from the [character + # position](rdoc-ref:StringScanner@Character+Position): + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos # => 0 + # scanner.getch # => "こ" # 3-byte character. + # scanner.charpos # => 1 + # scanner.pos # => 3 # def pos: () -> Integer # - # Sets the byte position of the scan pointer. - # - # s = StringScanner.new('test string') - # s.pos = 7 # -> 7 - # s.rest # -> "ring" + # call-seq: + # pos = n -> n + # pointer = n -> n + # Sets the [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # and the [character position](rdoc-ref:StringScanner@Positions); + # returns `n`. + # Does not affect [match values](rdoc-ref:StringScanner@Match+Values). + # For non-negative `n`, sets the position to `n`: + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 3 # => 3 + # scanner.rest # => "んにちは" + # scanner.charpos # => 1 + # + # For negative `n`, counts from the end of the [stored + # string](rdoc-ref:StringScanner@Stored+String): + # scanner.pos = -9 # => -9 + # scanner.pos # => 6 + # scanner.rest # => "にちは" + # scanner.charpos # => 2 # def pos=: (Integer) -> Integer # - # Returns the ***post**-match* (in the regular expression sense) of the last - # scan. + # Returns the substring that follows the matched substring + # from the most recent match attempt if it was successful, + # or `nil` otherwise; + # see [Basic Match Values](rdoc-ref:StringScanner@Basic+Match+Values): + # scanner = StringScanner.new('foobarbaz') + # scanner.post_match # => nil # - # s = StringScanner.new('test string') - # s.scan(/\w+/) # -> "test" - # s.scan(/\s+/) # -> " " - # s.pre_match # -> "test" - # s.post_match # -> "string" + # scanner.pos = 3 + # scanner.match?(/bar/) # => 3 + # scanner.post_match # => "baz" + # + # scanner.match?(/nope/) # => nil + # scanner.post_match # => nil # def post_match: () -> String # - # Returns the ***pre**-match* (in the regular expression sense) of the last - # scan. + # Returns the substring that precedes the matched substring + # from the most recent match attempt if it was successful, + # or `nil` otherwise; + # see [Basic Match Values](rdoc-ref:StringScanner@Basic+Match+Values): + # scanner = StringScanner.new('foobarbaz') + # scanner.pre_match # => nil # - # s = StringScanner.new('test string') - # s.scan(/\w+/) # -> "test" - # s.scan(/\s+/) # -> " " - # s.pre_match # -> "test" - # s.post_match # -> "string" + # scanner.pos = 3 + # scanner.exist?(/baz/) # => 6 + # scanner.pre_match # => "foobar" # Substring of entire string, not just target string. + # + # scanner.exist?(/nope/) # => nil + # scanner.pre_match # => nil # def pre_match: () -> String # - # Reset the scan pointer (index 0) and clear matching data. + # Sets both [byte position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) + # and [character position](rdoc-ref:StringScanner@Character+Position) to zero, + # and clears [match values](rdoc-ref:StringScanner@Match+Values); + # returns `self`: + # scanner = StringScanner.new('foobarbaz') + # scanner.exist?(/bar/) # => 6 + # scanner.reset # => # + # put_situation(scanner) + # # Situation: + # # pos: 0 + # # charpos: 0 + # # rest: "foobarbaz" + # # rest_size: 9 + # # => nil + # match_values_cleared?(scanner) # => true # def reset: () -> void # - # Returns the "rest" of the string (i.e. everything after the scan pointer). If - # there is no more data (eos? = true), it returns `""`. + # Returns the 'rest' of the [stored + # string](rdoc-ref:StringScanner@Stored+String) (all after the current + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)), + # which is the [target substring](rdoc-ref:StringScanner@Target+Substring): + # scanner = StringScanner.new('foobarbaz') + # scanner.rest # => "foobarbaz" + # scanner.pos = 3 + # scanner.rest # => "barbaz" + # scanner.terminate + # scanner.rest # => "" # def rest: () -> String @@ -567,9 +1199,19 @@ class StringScanner # - # `s.rest_size` is equivalent to `s.rest.size`. + # Returns the size (in bytes) of the #rest of the [stored + # string](rdoc-ref:StringScanner@Stored+String): + # scanner = StringScanner.new('foobarbaz') + # scanner.rest # => "foobarbaz" + # scanner.rest_size # => 9 + # scanner.pos = 3 + # scanner.rest # => "barbaz" + # scanner.rest_size # => 6 + # scanner.terminate + # scanner.rest # => "" + # scanner.rest_size # => 0 # def rest_size: () -> Integer @@ -584,19 +1226,53 @@ class StringScanner # - # Tries to match with `pattern` at the current position. If there's a match, the - # scanner advances the "scan pointer" and returns the matched string. Otherwise, - # the scanner returns `nil`. - # - # s = StringScanner.new('test string') - # p s.scan(/\w+/) # -> "test" - # p s.scan(/\w+/) # -> nil - # p s.scan(/\s+/) # -> " " - # p s.scan("str") # -> "str" - # p s.scan(/\w+/) # -> "ing" - # p s.scan(/./) # -> nil + # call-seq: + # scan(pattern) -> substring or nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # at the beginning of the [target + # substring](rdoc-ref:StringScanner@Target+Substring). + # If the match succeeds: + # * Returns the matched substring. + # * Increments the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) by + # `substring.bytesize`, + # and may increment the [character + # position](rdoc-ref:StringScanner@Character+Position). + # * Sets [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 6 + # scanner.scan(/に/) # => "に" + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "こん" + # # matched : "に" + # # post_match: "ちは" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["に", nil] + # # []: + # # [0]: "に" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 9 + # # charpos: 3 + # # rest: "ちは" + # # rest_size: 6 + # + # If the match fails: + # * Returns `nil`. + # * Does not increment byte and character positions. + # * Clears match values. + # scanner.scan(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def scan: (Regexp) -> String? @@ -614,16 +1290,54 @@ class StringScanner # - # Scans the string *until* the `pattern` is matched. Returns the substring up - # to and including the end of the match, advancing the scan pointer to that - # location. If there is no match, `nil` is returned. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan_until(/1/) # -> "Fri Dec 1" - # s.pre_match # -> "Fri Dec " - # s.scan_until(/XYZ/) # -> nil + # call-seq: + # scan_until(pattern) -> substring or nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # anywhere (at any + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) in the + # [target substring](rdoc-ref:StringScanner@Target+Substring). + # If the match attempt succeeds: + # * Sets [match values](rdoc-ref:StringScanner@Match+Values). + # * Sets the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to the end + # of the matched substring; + # may adjust the [character + # position](rdoc-ref:StringScanner@Character+Position). + # * Returns the matched substring. + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 6 + # scanner.scan_until(/ち/) # => "にち" + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "こんに" + # # matched : "ち" + # # post_match: "は" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["ち", nil] + # # []: + # # [0]: "ち" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 12 + # # charpos: 4 + # # rest: "は" + # # rest_size: 3 + # + # If the match attempt fails: + # * Clears match data. + # * Returns `nil`. + # * Does not update positions. + # scanner.scan_until(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def scan_until: (Regexp) -> String? @@ -640,110 +1354,237 @@ class StringScanner # - # Returns the amount of subgroups in the most recent match. The full match - # counts as a subgroup. + # Returns the count of captures if the most recent match attempt succeeded, + # `nil` otherwise; + # see [Captures Match Values](rdoc-ref:StringScanner@Captured+Match+Values): + # scanner = StringScanner.new('Fri Dec 12 1975 14:39') + # scanner.size # => nil # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - # s.size # -> 4 + # pattern = /(?\w+) (?\w+) (?\d+) / + # scanner.match?(pattern) + # scanner.values_at(*0..scanner.size) # => ["Fri Dec 12 ", "Fri", "Dec", "12", nil] + # scanner.size # => 4 + # + # scanner.match?(/nope/) # => nil + # scanner.size # => nil # def size: () -> Integer # - # Attempts to skip over the given `pattern` beginning with the scan pointer. If - # it matches, the scan pointer is advanced to the end of the match, and the - # length of the match is returned. Otherwise, `nil` is returned. - # - # It's similar to #scan, but without returning the matched string. - # - # s = StringScanner.new('test string') - # p s.skip(/\w+/) # -> 4 - # p s.skip(/\w+/) # -> nil - # p s.skip(/\s+/) # -> 1 - # p s.skip("st") # -> 2 - # p s.skip(/\w+/) # -> 4 - # p s.skip(/./) # -> nil + # call-seq: + # skip(pattern) match_size or nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # at the beginning of the [target + # substring](rdoc-ref:StringScanner@Target+Substring); + # If the match succeeds: + # * Increments the [byte + # position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) by + # substring.bytesize, + # and may increment the [character + # position](rdoc-ref:StringScanner@Character+Position). + # * Sets [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns the size (bytes) of the matched substring. + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 6 + # scanner.skip(/に/) # => 3 + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "こん" + # # matched : "に" + # # post_match: "ちは" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["に", nil] + # # []: + # # [0]: "に" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 9 + # # charpos: 3 + # # rest: "ちは" + # # rest_size: 6 + # + # scanner.skip(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def skip: (Regexp) -> Integer? # - # Advances the scan pointer until `pattern` is matched and consumed. Returns - # the number of bytes advanced, or `nil` if no match was found. - # - # Look ahead to match `pattern`, and advance the scan pointer to the *end* of - # the match. Return the number of characters advanced, or `nil` if the match - # was unsuccessful. - # - # It's similar to #scan_until, but without returning the intervening string. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.skip_until /12/ # -> 10 - # s # + # call-seq: + # skip_until(pattern) -> matched_substring_size or nil + # Attempts to [match](rdoc-ref:StringScanner@Matching) the given `pattern` + # anywhere (at any + # [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29)) in the + # [target substring](rdoc-ref:StringScanner@Target+Substring); + # does not modify the positions. + # If the match attempt succeeds: + # * Sets [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns the size of the matched substring. + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.pos = 6 + # scanner.skip_until(/ち/) # => 6 + # put_match_values(scanner) + # # Basic match values: + # # matched?: true + # # matched_size: 3 + # # pre_match: "こんに" + # # matched : "ち" + # # post_match: "は" + # # Captured match values: + # # size: 1 + # # captures: [] + # # named_captures: {} + # # values_at: ["ち", nil] + # # []: + # # [0]: "ち" + # # [1]: nil + # put_situation(scanner) + # # Situation: + # # pos: 12 + # # charpos: 4 + # # rest: "は" + # # rest_size: 3 + # + # If the match attempt fails: + # * Clears match values. + # * Returns `nil`. + # scanner.skip_until(/nope/) # => nil + # match_values_cleared?(scanner) # => true # def skip_until: (Regexp) -> Integer? # - # Returns the string being scanned. + # Returns the [stored string](rdoc-ref:StringScanner@Stored+String): + # scanner = StringScanner.new('foobar') + # scanner.string # => "foobar" + # scanner.concat('baz') + # scanner.string # => "foobarbaz" # def string: () -> String # - # Changes the string being scanned to `str` and resets the scanner. Returns - # `str`. + # Replaces the [stored string](rdoc-ref:StringScanner@Stored+String) with the + # given `other_string`: + # * Sets both [positions](rdoc-ref:StringScanner@Positions) to zero. + # * Clears [match values](rdoc-ref:StringScanner@Match+Values). + # * Returns `other_string`. + # scanner = StringScanner.new('foobar') + # scanner.scan(/foo/) + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "bar" + # # rest_size: 3 + # match_values_cleared?(scanner) # => false + # + # scanner.string = 'baz' # => "baz" + # put_situation(scanner) + # # Situation: + # # pos: 0 + # # charpos: 0 + # # rest: "baz" + # # rest_size: 3 + # match_values_cleared?(scanner) # => true # def string=: (String) -> String # - # Sets the scan pointer to the end of the string and clear matching data. + # call-seq: + # terminate -> self + # Sets the scanner to end-of-string; + # returns `self`: + # * Sets both [positions](rdoc-ref:StringScanner@Positions) to end-of-stream. + # * Clears [match values](rdoc-ref:StringScanner@Match+Values). + # scanner = StringScanner.new(HIRAGANA_TEXT) + # scanner.string # => "こんにちは" + # scanner.scan_until(/に/) + # put_situation(scanner) + # # Situation: + # # pos: 9 + # # charpos: 3 + # # rest: "ちは" + # # rest_size: 6 + # match_values_cleared?(scanner) # => false + # + # scanner.terminate # => # + # put_situation(scanner) + # # Situation: + # # pos: 15 + # # charpos: 5 + # # rest: "" + # # rest_size: 0 + # match_values_cleared?(scanner) # => true # def terminate: () -> void # - # Sets the scan pointer to the previous position. Only one previous position is - # remembered, and it changes with each scanning operation. - # - # s = StringScanner.new('test string') - # s.scan(/\w+/) # => "test" - # s.unscan - # s.scan(/../) # => "te" - # s.scan(/\d/) # => nil - # s.unscan # ScanError: unscan failed: previous match record not exist + # Sets the [position](rdoc-ref:StringScanner@Byte+Position+-28Position-29) to + # its value previous to the recent successful + # [match](rdoc-ref:StringScanner@Matching) attempt: + # scanner = StringScanner.new('foobarbaz') + # scanner.scan(/foo/) + # put_situation(scanner) + # # Situation: + # # pos: 3 + # # charpos: 3 + # # rest: "barbaz" + # # rest_size: 6 + # scanner.unscan + # # => # + # put_situation(scanner) + # # Situation: + # # pos: 0 + # # charpos: 0 + # # rest: "foobarbaz" + # # rest_size: 9 + # + # Raises an exception if match values are clear: + # scanner.scan(/nope/) # => nil + # match_values_cleared?(scanner) # => true + # scanner.unscan # Raises StringScanner::Error. # def unscan: () -> void # - # Returns the subgroups in the most recent match at the given indices. If - # nothing was priorly matched, it returns nil. - # - # s = StringScanner.new("Fri Dec 12 1975 14:39") - # s.scan(/(\w+) (\w+) (\d+) /) # -> "Fri Dec 12 " - # s.values_at 0, -1, 5, 2 # -> ["Fri Dec 12 ", "12", nil, "Dec"] - # s.scan(/(\w+) (\w+) (\d+) /) # -> nil - # s.values_at 0, -1, 5, 2 # -> nil + # Returns an array of captured substrings, or `nil` of none. + # For each `specifier`, the returned substring is `[specifier]`; + # see #[]. + # scanner = StringScanner.new('Fri Dec 12 1975 14:39') + # pattern = /(?\w+) (?\w+) (?\d+) / + # scanner.match?(pattern) + # scanner.values_at(*0..3) # => ["Fri Dec 12 ", "Fri", "Dec", "12"] + # scanner.values_at(*%i[wday month day]) # => ["Fri", "Dec", "12"] # def values_at: (*Integer) -> Array[String]? @@ -751,24 +1592,32 @@ class StringScanner # - # Creates a new StringScanner object to scan over the given `string`. - # - # If `fixed_anchor` is `true`, `\A` always matches the beginning of the string. - # Otherwise, `\A` always matches the current position. - # - # `dup` argument is obsolete and not used now. + # Returns a new `StringScanner` object whose [stored + # string](rdoc-ref:StringScanner@Stored+String) + # is the given `string`; + # sets the [fixed-anchor + # property](rdoc-ref:StringScanner@Fixed-Anchor+Property): + # scanner = StringScanner.new('foobarbaz') + # scanner.string # => "foobarbaz" + # scanner.fixed_anchor? # => false + # put_situation(scanner) + # # Situation: + # # pos: 0 + # # charpos: 0 + # # rest: "foobarbaz" + # # rest_size: 9 # def initialize: (String, ?bool dup, ?fixed_anchor: bool) -> untyped # - # Duplicates a StringScanner object. + # Returns a shallow copy of `self`; + # the [stored string](rdoc-ref:StringScanner@Stored+String) in the copy is the + # same string as in `self`. # def initialize_copy: (StringScanner) -> void end diff --git a/stdlib/tempfile/0/tempfile.rbs b/stdlib/tempfile/0/tempfile.rbs index 1cfe8db75a..9a2f706e9a 100644 --- a/stdlib/tempfile/0/tempfile.rbs +++ b/stdlib/tempfile/0/tempfile.rbs @@ -1,16 +1,58 @@ # -# A utility class for managing temporary files. When you create a Tempfile -# object, it will create a temporary file with a unique filename. A Tempfile -# objects behaves just like a File object, and you can perform all the usual -# file operations on it: reading data, writing data, changing its permissions, -# etc. So although this class does not explicitly document all instance methods -# supported by File, you can in fact call any File instance method on a Tempfile -# object. +# A utility class for managing temporary files. +# +# There are two kind of methods of creating a temporary file: +# +# * Tempfile.create (recommended) +# * Tempfile.new and Tempfile.open (mostly for backward compatibility, not +# recommended) +# +# Tempfile.create creates a usual File object. The timing of file deletion is +# predictable. Also, it supports open-and-unlink technique which removes the +# temporary file immediately after creation. +# +# Tempfile.new and Tempfile.open creates a Tempfile object. The created file is +# removed by the GC (finalizer). The timing of file deletion is not predictable. # # ## Synopsis # # require 'tempfile' # +# # Tempfile.create with a block +# # The filename are choosen automatically. +# # (You can specify the prefix and suffix of the filename by an optional argument.) +# Tempfile.create {|f| +# f.puts "foo" +# f.rewind +# f.read # => "foo\n" +# } # The file is removed at block exit. +# +# # Tempfile.create without a block +# # You need to unlink the file in non-block form. +# f = Tempfile.create +# f.puts "foo" +# f.close +# File.unlink(f.path) # You need to unlink the file. +# +# # Tempfile.create(anonymous: true) without a block +# f = Tempfile.create(anonymous: true) +# # The file is already removed because anonymous. +# f.path # => "/tmp/" (no filename since no file) +# f.puts "foo" +# f.rewind +# f.read # => "foo\n" +# f.close +# +# # Tempfile.create(anonymous: true) with a block +# Tempfile.create(anonymous: true) {|f| +# # The file is already removed because anonymous. +# f.path # => "/tmp/" (no filename since no file) +# f.puts "foo" +# f.rewind +# f.read # => "foo\n" +# } +# +# # Not recommended: Tempfile.new without a block # file = Tempfile.new('foo') # file.path # => A unique filename in the OS's temp directory, # # e.g.: "/tmp/foo.24722.0" @@ -21,7 +63,27 @@ # file.close # file.unlink # deletes the temp file # -# ## Good practices +# ## About Tempfile.new and Tempfile.open +# +# This section does not apply to Tempfile.create because it returns a File +# object (not a Tempfile object). +# +# When you create a Tempfile object, it will create a temporary file with a +# unique filename. A Tempfile objects behaves just like a File object, and you +# can perform all the usual file operations on it: reading data, writing data, +# changing its permissions, etc. So although this class does not explicitly +# document all instance methods supported by File, you can in fact call any File +# instance method on a Tempfile object. +# +# A Tempfile object has a finalizer to remove the temporary file. This means +# that the temporary file is removed via GC. This can cause several problems: +# +# * Long GC intervals and conservative GC can accumulate temporary files that +# are not removed. +# * Temporary files are not removed if Ruby exits abnormally (such as SIGKILL, +# SEGV). +# +# There are legacy good practices for Tempfile.new and Tempfile.open as follows. # # ### Explicit close # @@ -61,12 +123,17 @@ # this if you do not want any other processes to be able to read from or write # to the Tempfile, and you do not need to know the Tempfile's filename either. # +# Also, this guarantees the temporary file is removed even if Ruby exits +# abnormally. The OS reclaims the storage for the temporary file when the file +# is closed or the Ruby process exits (normally or abnormally). +# # For example, a practical use case for unlink-after-creation would be this: you # need a large byte buffer that's too large to comfortably fit in RAM, e.g. when # you're writing a web server and you want to buffer the client's file upload # data. # -# Please refer to #unlink for more information and a code example. +# `Tempfile.create(anonymous: true)` supports this behavior. It also works on +# Windows. # # ## Minor notes # @@ -80,7 +147,7 @@ class Tempfile < File # # Creates a file in the underlying file system; returns a new File object based # on that file. @@ -94,8 +161,9 @@ class Tempfile < File # Permissions](rdoc-ref:File@File+Permissions). # * Mode is `'w+'` (read/write mode, positioned at the end). # - # With no block, the file is not removed automatically, and so should be - # explicitly removed. + # The temporary file removal depends on the keyword argument `anonymous` and + # whether a block is given or not. See the description about the `anonymous` + # keyword argument later. # # Example: # @@ -103,11 +171,36 @@ class Tempfile < File # f.class # => File # f.path # => "/tmp/20220505-9795-17ky6f6" # f.stat.mode.to_s(8) # => "100600" + # f.close # File.exist?(f.path) # => true # File.unlink(f.path) # File.exist?(f.path) # => false # - # Argument `basename`, if given, may be one of: + # Tempfile.create {|f| + # f.puts "foo" + # f.rewind + # f.read # => "foo\n" + # f.path # => "/tmp/20240524-380207-oma0ny" + # File.exist?(f.path) # => true + # } # The file is removed at block exit. + # + # f = Tempfile.create(anonymous: true) + # # The file is already removed because anonymous + # f.path # => "/tmp/" (no filename since no file) + # f.puts "foo" + # f.rewind + # f.read # => "foo\n" + # f.close + # + # Tempfile.create(anonymous: true) {|f| + # # The file is already removed because anonymous + # f.path # => "/tmp/" (no filename since no file) + # f.puts "foo" + # f.rewind + # f.read # => "foo\n" + # } + # + # The argument `basename`, if given, may be one of the following: # # * A string: the generated filename begins with `basename`: # @@ -118,25 +211,46 @@ class Tempfile < File # # Tempfile.create(%w/foo .jpg/) # => # # - # With arguments `basename` and `tmpdir`, the file is created in directory + # With arguments `basename` and `tmpdir`, the file is created in the directory # `tmpdir`: # # Tempfile.create('foo', '.') # => # # - # Keyword arguments `mode` and `options` are passed directly to method + # Keyword arguments `mode` and `options` are passed directly to the method # [File.open](rdoc-ref:File.open): # - # * The value given with `mode` must be an integer, and may be expressed as - # the logical OR of constants defined in + # * The value given for `mode` must be an integer and may be expressed as the + # logical OR of constants defined in # [File::Constants](rdoc-ref:File::Constants). # * For `options`, see [Open Options](rdoc-ref:IO@Open+Options). # - # With a block given, creates the file as above, passes it to the block, and - # returns the block's value; before the return, the file object is closed and - # the underlying file is removed: + # The keyword argument `anonymous` specifies when the file is removed. + # + # * `anonymous=false` (default) without a block: the file is not removed. + # * `anonymous=false` (default) with a block: the file is removed after the + # block exits. + # * `anonymous=true` without a block: the file is removed before returning. + # * `anonymous=true` with a block: the file is removed before the block is + # called. + # + # In the first case (`anonymous=false` without a block), the file is not removed + # automatically. It should be explicitly closed. It can be used to rename to the + # desired filename. If the file is not needed, it should be explicitly removed. + # + # The File#path method of the created file object returns the temporary + # directory with a trailing slash when `anonymous` is true. + # + # When a block is given, it creates the file as described above, passes it to + # the block, and returns the block's value. Before the returning, the file + # object is closed and the underlying file is removed: # # Tempfile.create {|file| file.path } # => "/tmp/20220505-9795-rkists" # + # Implementation note: + # + # The keyword argument +anonymous=true+ is implemented using FILE_SHARE_DELETE + # on Windows. O_TMPFILE is used on Linux. + # # Related: Tempfile.new. # def self.create: (?String | [ String, String ] basename, ?String? tmpdir, ?mode: Integer, **untyped) -> File diff --git a/stdlib/time/0/time.rbs b/stdlib/time/0/time.rbs index f657523c4a..de63b2f6a7 100644 --- a/stdlib/time/0/time.rbs +++ b/stdlib/time/0/time.rbs @@ -43,7 +43,7 @@ class Time # # This method **does not** function as a validator. If the input string does # not match valid formats strictly, you may get a cryptic result. Should - # consider to use `Time.strptime` instead of this method as possible. + # consider to use Time.strptime instead of this method as possible. # # require 'time' # @@ -147,6 +147,8 @@ class Time # the format of the input string, you provide a second argument that describes # the format of the string. # + # Raises ArgumentError if the date or format is invalid. + # # If a block is given, the year described in `date` is converted by the block. # For example: # @@ -281,7 +283,7 @@ class Time # : Year which may include century, if provided # # %z - # : Time zone as hour offset from UTC (e.g. +0900) + # : Time zone as hour offset from UTC (e.g. +0900) # # %Z # : Time zone name @@ -454,10 +456,22 @@ class Time # def xmlschema: (?Integer fraction_digits) -> String - # + # + # Parses `time` as a dateTime defined by the XML Schema and converts it to a + # Time object. The format is a restricted version of the format defined by ISO + # 8601. + # + # ArgumentError is raised if `time` is not compliant with the format or if the + # Time class cannot represent the specified time. + # + # See #xmlschema for more information on this format. + # + # require 'time' + # + # Time.xmlschema("2011-10-05T22:26:12-04:00") + # #=> 2011-10-05 22:26:12-04:00 + # + # You must require 'time' to use this method. # alias iso8601 xmlschema end diff --git a/stdlib/timeout/0/timeout.rbs b/stdlib/timeout/0/timeout.rbs index 3ef05df9a1..997fad2bd3 100644 --- a/stdlib/timeout/0/timeout.rbs +++ b/stdlib/timeout/0/timeout.rbs @@ -4,7 +4,7 @@ # ## Synopsis # # require 'timeout' -# status = Timeout::timeout(5) { +# status = Timeout.timeout(5) { # # Something that should be interrupted if it takes more than 5 seconds... # } # @@ -13,10 +13,6 @@ # Timeout provides a way to auto-terminate a potentially long-running operation # if it hasn't finished in a fixed amount of time. # -# Previous versions didn't use a module for namespacing, however #timeout is -# provided for backwards compatibility. You should prefer Timeout.timeout -# instead. -# # ## Copyright # # Copyright @@ -34,9 +30,10 @@ module Timeout # `sec` seconds to complete. # # `sec` - # : Number of seconds to wait for the block to terminate. Any number may be - # used, including Floats to specify fractional seconds. A value of 0 or - # `nil` will execute the block without any timeout. + # : Number of seconds to wait for the block to terminate. Any non-negative + # number or nil may be used, including Floats to specify fractional seconds. + # A value of 0 or `nil` will execute the block without any timeout. Any + # negative number will raise an ArgumentError. # # `klass` # : Exception Class to raise if the block fails to terminate in `sec` seconds. @@ -78,4 +75,7 @@ class Timeout::Error < RuntimeError attr_reader thread: Thread? end +# +# The version +# Timeout::VERSION: String diff --git a/stdlib/tmpdir/0/tmpdir.rbs b/stdlib/tmpdir/0/tmpdir.rbs index ba1169238c..a41b57ee48 100644 --- a/stdlib/tmpdir/0/tmpdir.rbs +++ b/stdlib/tmpdir/0/tmpdir.rbs @@ -6,6 +6,9 @@ class Dir # --> # Returns the operating system's temporary file path. # + # require 'tmpdir' + # Dir.tmpdir # => "/tmp" + # def self.tmpdir: () -> String # # Dir.mktmpdir creates a temporary directory. # + # require 'tmpdir' + # Dir.mktmpdir {|dir| + # # use the directory + # } + # # The directory is created with 0700 permission. Application should not change # the permission to make the temporary directory accessible from other users. # diff --git a/stdlib/uri/0/common.rbs b/stdlib/uri/0/common.rbs index fa78652f12..e02d9409cc 100644 --- a/stdlib/uri/0/common.rbs +++ b/stdlib/uri/0/common.rbs @@ -24,7 +24,7 @@ end # # URI is a module providing classes to handle Uniform Resource Identifiers -# ([RFC2396](http://tools.ietf.org/html/rfc2396)). +# ([RFC2396](https://www.rfc-editor.org/rfc/rfc2396)). # # ## Features # @@ -71,14 +71,14 @@ end # A good place to view an RFC spec is http://www.ietf.org/rfc.html. # # Here is a list of all related RFC's: -# * [RFC822](http://tools.ietf.org/html/rfc822) -# * [RFC1738](http://tools.ietf.org/html/rfc1738) -# * [RFC2255](http://tools.ietf.org/html/rfc2255) -# * [RFC2368](http://tools.ietf.org/html/rfc2368) -# * [RFC2373](http://tools.ietf.org/html/rfc2373) -# * [RFC2396](http://tools.ietf.org/html/rfc2396) -# * [RFC2732](http://tools.ietf.org/html/rfc2732) -# * [RFC3986](http://tools.ietf.org/html/rfc3986) +# * [RFC822](https://www.rfc-editor.org/rfc/rfc822) +# * [RFC1738](https://www.rfc-editor.org/rfc/rfc1738) +# * [RFC2255](https://www.rfc-editor.org/rfc/rfc2255) +# * [RFC2368](https://www.rfc-editor.org/rfc/rfc2368) +# * [RFC2373](https://www.rfc-editor.org/rfc/rfc2373) +# * [RFC2396](https://www.rfc-editor.org/rfc/rfc2396) +# * [RFC2732](https://www.rfc-editor.org/rfc/rfc2732) +# * [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) # # ## Class tree # @@ -518,9 +518,6 @@ URI::ABS_URI: Regexp URI::ABS_URI_REF: Regexp -# -# URI::Parser.new -# URI::DEFAULT_PARSER: URI::RFC2396_Parser URI::ESCAPED: Regexp diff --git a/stdlib/uri/0/ftp.rbs b/stdlib/uri/0/ftp.rbs index 43c842d6a7..74e3e6cd64 100644 --- a/stdlib/uri/0/ftp.rbs +++ b/stdlib/uri/0/ftp.rbs @@ -6,7 +6,7 @@ module URI # This class will be redesigned because of difference of implementations; the # structure of its path. draft-hoffman-ftp-uri-04 is a draft but it is a good # summary about the de facto spec. - # http://tools.ietf.org/html/draft-hoffman-ftp-uri-04 + # https://datatracker.ietf.org/doc/html/draft-hoffman-ftp-uri-04 # class FTP < Generic end diff --git a/stdlib/uri/0/generic.rbs b/stdlib/uri/0/generic.rbs index de6090345c..c32d7f1a01 100644 --- a/stdlib/uri/0/generic.rbs +++ b/stdlib/uri/0/generic.rbs @@ -1,6 +1,6 @@ # # URI is a module providing classes to handle Uniform Resource Identifiers -# ([RFC2396](http://tools.ietf.org/html/rfc2396)). +# ([RFC2396](https://www.rfc-editor.org/rfc/rfc2396)). # # ## Features # @@ -47,14 +47,14 @@ # A good place to view an RFC spec is http://www.ietf.org/rfc.html. # # Here is a list of all related RFC's: -# * [RFC822](http://tools.ietf.org/html/rfc822) -# * [RFC1738](http://tools.ietf.org/html/rfc1738) -# * [RFC2255](http://tools.ietf.org/html/rfc2255) -# * [RFC2368](http://tools.ietf.org/html/rfc2368) -# * [RFC2373](http://tools.ietf.org/html/rfc2373) -# * [RFC2396](http://tools.ietf.org/html/rfc2396) -# * [RFC2732](http://tools.ietf.org/html/rfc2732) -# * [RFC3986](http://tools.ietf.org/html/rfc3986) +# * [RFC822](https://www.rfc-editor.org/rfc/rfc822) +# * [RFC1738](https://www.rfc-editor.org/rfc/rfc1738) +# * [RFC2255](https://www.rfc-editor.org/rfc/rfc2255) +# * [RFC2368](https://www.rfc-editor.org/rfc/rfc2368) +# * [RFC2373](https://www.rfc-editor.org/rfc/rfc2373) +# * [RFC2396](https://www.rfc-editor.org/rfc/rfc2396) +# * [RFC2732](https://www.rfc-editor.org/rfc/rfc2732) +# * [RFC3986](https://www.rfc-editor.org/rfc/rfc3986) # # ## Class tree # @@ -813,7 +813,7 @@ module URI # ## Description # # URI has components listed in order of decreasing significance from left to - # right, see RFC3986 https://tools.ietf.org/html/rfc3986 1.2.3. + # right, see RFC3986 https://www.rfc-editor.org/rfc/rfc3986 1.2.3. # # ## Usage # diff --git a/stdlib/uri/0/http.rbs b/stdlib/uri/0/http.rbs index 62534f112a..3fb745ba1e 100644 --- a/stdlib/uri/0/http.rbs +++ b/stdlib/uri/0/http.rbs @@ -55,7 +55,7 @@ module URI # ## Description # # Returns the authority for an HTTP uri, as defined in - # https://datatracker.ietf.org/doc/html/rfc3986/#section-3.2. + # https://www.rfc-editor.org/rfc/rfc3986#section-3.2. # # Example: # @@ -72,7 +72,7 @@ module URI # ## Description # # Returns the origin for an HTTP uri, as defined in - # https://datatracker.ietf.org/doc/html/rfc6454. + # https://www.rfc-editor.org/rfc/rfc6454. # # Example: # diff --git a/stdlib/zlib/0/gzip_reader.rbs b/stdlib/zlib/0/gzip_reader.rbs index 81726528de..364f80bda0 100644 --- a/stdlib/zlib/0/gzip_reader.rbs +++ b/stdlib/zlib/0/gzip_reader.rbs @@ -183,7 +183,7 @@ module Zlib # # See Zlib::GzipReader documentation for a description. # @@ -225,7 +225,7 @@ module Zlib # rdoc-file=ext/zlib/zlib.c # - gzipreader.readpartial(maxlen [, outbuf]) => string, outbuf # --> - # Reads at most *maxlen* bytes from the gziped stream but it blocks only if + # Reads at most *maxlen* bytes from the gzipped stream but it blocks only if # *gzipreader* has no data immediately available. If the optional *outbuf* # argument is present, it must reference a String, which will receive the data. # It raises `EOFError` on end of file. diff --git a/stdlib/zlib/0/zstream.rbs b/stdlib/zlib/0/zstream.rbs index 108e53a6ae..ec44ba6033 100644 --- a/stdlib/zlib/0/zstream.rbs +++ b/stdlib/zlib/0/zstream.rbs @@ -113,7 +113,7 @@ module Zlib # rdoc-file=ext/zlib/zlib.c # - data_type() # --> - # Guesses the type of the data which have been inputed into the stream. The + # Guesses the type of the data which have been inputted into the stream. The # returned value is either `BINARY`, `ASCII`, or `UNKNOWN`. # def data_type: () -> String