[ci skip] Rdoc enhancements for Array (#3063)

* Per @nobu review

* Rdoc enhancements for Array

* Responses to review
This commit is contained in:
Burdette Lamar 2020-05-15 16:12:40 -05:00 committed by GitHub
parent a3cd01524c
commit 24739c62e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
Notes: git 2020-05-16 06:13:06 +09:00
Merged-By: drbrain <drbrain@segment7.net>
2 changed files with 226 additions and 84 deletions

274
array.c
View File

@ -935,21 +935,26 @@ rb_check_to_array(VALUE ary)
/* /*
* call-seq: * call-seq:
* Array.try_convert(obj) -> array or nil * Array.try_convert(obj) -> new_array or nil
* *
* Tries to convert +obj+ into an array, using the +to_ary+ method. Returns * Tries to convert +obj+ to an \Array.
* the converted array or +nil+ if +obj+ cannot be converted.
* This method can be used to check if an argument is an array.
* *
* Array.try_convert([1]) #=> [1] * When +obj+ is an
* Array.try_convert("1") #=> nil * {Array-convertible object}[doc/implicit_conversion_rdoc.html#label-Array-Convertible+Objects]
* (implements +to_ary+),
* returns the \Array object created by converting it:
* *
* if tmp = Array.try_convert(arg) * class ToAryReturnsArray < Set
* # the argument is an array * def to_ary
* elsif tmp = String.try_convert(arg) * self.to_a
* # the argument is a string * end
* end * end
* as = ToAryReturnsArray.new([:foo, :bar, :baz])
* Array.try_convert(as) # => [:foo, :bar, :baz]
* *
* Returns +nil+ if +obj+ is not \Array-convertible:
*
* Array.try_convert(:foo) # => nil
*/ */
static VALUE static VALUE
@ -960,58 +965,96 @@ rb_ary_s_try_convert(VALUE dummy, VALUE ary)
/* /*
* call-seq: * call-seq:
* Array.new(size=0, default=nil) * Array.new -> new_empty_array
* Array.new(array) * Array.new(array) -> new_array
* Array.new(size) {|index| block } * Array.new(size) -> new_array
* Array.new(size, default_value) -> new_array
* Array.new(size) {|index| ... } -> new_array
* *
* Returns a new array. * Returns a new \Array.
* *
* In the first form, if no arguments are sent, the new array will be empty. * Argument +array+, if given, must be an
* When a +size+ and an optional +default+ are sent, an array is created with * {Array-convertible object}[doc/implicit_conversion_rdoc.html#label-Array-Convertible+Objects]
* +size+ copies of +default+. Take notice that all elements will reference the * (implements +to_ary+).
* same object +default+.
* *
* The second form creates a copy of the array passed as a parameter (the * Argument +size+, if given must be an
* array is generated by calling to_ary on the parameter). * {Integer-convertible object}[doc/implicit_conversion_rdoc.html#label-Integer-Convertible+Objects]
* (implements +to_int+).
* *
* first_array = ["Matz", "Guido"] * Argument +default_value+ may be any object.
* *
* second_array = Array.new(first_array) #=> ["Matz", "Guido"] * ---
* *
* first_array.equal? second_array #=> false * With no block and no arguments, returns a new empty \Array object:
* *
* In the last form, an array of the given size is created. Each element in * a = Array.new
* this array is created by passing the element's index to the given block * a # => []
* and storing the return value.
* *
* Array.new(3) {|index| index ** 2} * With no block and a single argument +array+,
* # => [0, 1, 4] * returns a new \Array formed from +array+:
* *
* == Common gotchas * a = Array.new([:foo, 'bar', 2])
* a.class # => Array
* a # => [:foo, "bar", 2]
* *
* When sending the second parameter, the same object will be used as the * With no block and a single argument +size+,
* value for all the array elements: * returns a new \Array of the given size
* whose elements are all +nil+:
* *
* a = Array.new(2, Hash.new) * a = Array.new(0)
* # => [{}, {}] * a # => []
* a = Array.new(3)
* a # => [nil, nil, nil]
* *
* a[0]['cat'] = 'feline' * With no block and arguments +size+ and +default_value+,
* a # => [{"cat"=>"feline"}, {"cat"=>"feline"}] * returns an \Array of the given size;
* each element is that same +default_value+:
* *
* a[1]['cat'] = 'Felix' * a = Array.new(3, 'x')
* a # => [{"cat"=>"Felix"}, {"cat"=>"Felix"}] * a # => ['x', 'x', 'x']
* a[1].equal?(a[0]) # => true # Identity check.
* a[2].equal?(a[0]) # => true # Identity check.
* *
* Since all the Array elements store the same hash, changes to one of them * With a block and argument +size+,
* will affect them all. * 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:
* *
* If multiple copies are what you want, you should use the block * a = Array.new(3) { |index| "Element #{index}" }
* version which uses the result of that block each time an element * a # => ["Element 0", "Element 1", "Element 2"]
* of the array needs to be initialized:
* *
* a = Array.new(2) {Hash.new} * With a block and no argument,
* a[0]['cat'] = 'feline' * or a single argument +0+,
* a # => [{"cat"=>"feline"}, {}] * ignores the block and returns a new empty \Array:
* *
* a = Array.new(0) { |n| fail 'Cannot happen' }
* a # => []
* a = Array.new { |n| fail 'Cannot happen' }
* a # => []
*
* With a block and arguments +size+ and +default_value+,
* gives a warning message
* ('warning: block supersedes default value argument'),
* and assigns elements from the block's return values:
*
* Array.new(4, :default) {} # => [nil, nil, nil, nil]
*
* ---
*
* Raises an exception if +size+ is a negative integer:
*
* # Raises ArgumentError (negative array size):
* Array.new(-1)
* # Raises ArgumentError (negative array size):
* Array.new(-1, :default)
* # Raises ArgumentError (negative array size):
* Array.new(-1) { |n| }
*
* Raises an exception if the single argument is neither \Array-convertible
* nor \Integer-convertible.
*
* # Raises TypeError (no implicit conversion of Symbol into Integer):
* Array.new(:foo)
*/ */
static VALUE static VALUE
@ -1193,18 +1236,20 @@ ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos
/* /*
* call-seq: * call-seq:
* ary << obj -> ary * ary << obj -> self
* *
* Append---Pushes the given object on to the end of this array. This * Appends +obj+ to +ary+; returns +self+:
* expression returns the array itself, so several appends
* may be chained together.
* *
* a = [ 1, 2 ] * a = [:foo, 'bar', 2]
* a << "c" << "d" << [ 3, 4 ] * a1 = a << :baz
* #=> [ 1, 2, "c", "d", [ 3, 4 ] ] * a1 # => [:foo, "bar", 2, :baz]
* a * a1.equal?(a) # => true
* #=> [ 1, 2, "c", "d", [ 3, 4 ] ]
* *
* Appends +obj+ as one element, even if it is another \Array:
*
* a = [:foo, 'bar', 2]
* a1 = a << [3, 4] # =>
* a1 # => [:foo, "bar", 2, [3, 4]]
*/ */
VALUE VALUE
@ -1232,19 +1277,21 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len)
/* /*
* call-seq: * call-seq:
* ary.push(obj, ...) -> ary * ary.push(*objects) -> self
* ary.append(obj, ...) -> ary * ary.append(*objects) -> self
* *
* Append --- Pushes the given object(s) on to the end of this array. This * Appends each argument in +objects+ to the array; returns +self+:
* expression returns the array itself, so several appends
* may be chained together. See also Array#pop for the opposite
* effect.
* *
* a = [ "a", "b", "c" ] * a = [:foo, 'bar', 2]
* a.push("d", "e", "f") * a1 = a.push(:baz, :bat)
* #=> ["a", "b", "c", "d", "e", "f"] * a1 # => [:foo, "bar", 2, :baz, :bat]
* [1, 2, 3].push(4).push(5) * a1.equal?(a) # => true
* #=> [1, 2, 3, 4, 5] *
* Appends each argument as one 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]]
*/ */
static VALUE static VALUE
@ -1274,20 +1321,62 @@ rb_ary_pop(VALUE ary)
/* /*
* call-seq: * call-seq:
* ary.pop -> obj or nil * ary.pop -> obj or nil
* ary.pop(n) -> new_ary * ary.pop(n) -> new_array
* *
* Removes the last element from +self+ and returns it, or * Removes and returns trailing elements from the array.
* +nil+ if the array is empty.
* *
* If a number +n+ is given, returns an array of the last +n+ elements * Argument +n+, if given, must be an
* (or less) just like <code>array.slice!(-n, n)</code> does. See also * {Integer-convertible object}[doc/implicit_conversion_rdoc.html#label-Integer-Convertible+Objects]
* Array#push for the opposite effect. * (implements +to_int+).
* *
* a = [ "a", "b", "c", "d" ] * ---
* a.pop #=> "d" *
* a.pop(2) #=> ["b", "c"] * When no argument is given and the array is not empty,
* a #=> ["a"] * removes and returns the last element in the array:
*
* a = [:foo, 'bar', 2]
* a.pop # => 2
* a # => [:foo, "bar"]
*
* Returns +nil+ if the array is empty:
*
* a = []
* a.pop # => nil
*
* ---
*
* When argument +n+ is given and is non-negative and in range,
* removes and returns the last +n+ elements in a new \Array:
*
* a = [:foo, 'bar', 2]
* a1 = a.pop(2)
* a1 # => ["bar", 2]
* a # => [:foo]
* a.pop(0) # => []
*
* If +n+ is positive and out of range,
* removes and returns all elements:
*
* a = [:foo, 'bar', 2]
* a1 = a.pop(50)
* a1 # => [:foo, "bar", 2]
* a # => []
* a.pop(1) # => []
*
* ---
*
* Raises an exception if +n+ is negative:
*
* a = [:foo, 'bar', 2]
* # Raises ArgumentError (negative array size):
* a1 = a.pop(-1)
*
* Raises an exception if +n+ is not \Integer-convertible (implements +to_int+).
*
* a = [:foo, 'bar', 2]
* # Raises TypeError (no implicit conversion of String into Integer):
* a1 = a.pop('x')
*/ */
static VALUE static VALUE
@ -6621,12 +6710,32 @@ rb_ary_deconstruct(VALUE ary)
} }
/* /*
* Arrays are ordered, integer-indexed collections of any object. * An \Array is an ordered, integer-indexed collection of objects,
* called _elements_. Any object may be an \Array element.
* *
* Array indexing starts at 0, as in C or Java. A negative index is assumed * == \Array Indexes
* to be relative to the end of the array---that is, an index of -1 indicates *
* the last element of the array, -2 is the next to last element in the * \Array indexing starts at 0, as in C or Java.
* array, and so on. *
* A positive index is an offset from the first element:
* - Index 0 indicates the first element.
* - Index 1 indicates the second element.
* - ...
*
* A negative index is an offset, backwards, from the end of the array:
* - Index -1 indicates the last element.
* - Index -2 indicates the next-to-last element.
* - ...
*
* A non-negative index is <i>in range</i> if it is smaller than
* the size of the array. For a 3-element array:
* - Indexes 0 through 2 are in range.
* - Index 3 is out of range.
*
* A negative index is <i>in range</i> if its absolute value is
* not larger than the size of the array. For a 3-element array:
* - Indexes -1 through -3 are in range.
* - Index -4 is out of range.
* *
* == Creating Arrays * == Creating Arrays
* *
@ -6855,7 +6964,6 @@ rb_ary_deconstruct(VALUE ary)
* arr = [1, 2, 3, 4, 5, 6] * arr = [1, 2, 3, 4, 5, 6]
* arr.keep_if {|a| a < 4} #=> [1, 2, 3] * arr.keep_if {|a| a < 4} #=> [1, 2, 3]
* arr #=> [1, 2, 3] * arr #=> [1, 2, 3]
*
*/ */
void void

View File

@ -30,7 +30,41 @@ NoMethodError.
You may also use <code>::</code> to designate a receiver, but this is rarely You may also use <code>::</code> to designate a receiver, but this is rarely
used due to the potential for confusion with <code>::</code> for namespaces. used due to the potential for confusion with <code>::</code> for namespaces.
=== Safe navigation operator === Chaining \Method Calls
You can "chain" method calls by immediately following one method call with another.
This example chains methods Array#append and Array#compact:
a = [:foo, 'bar', 2]
a1 = [:baz, nil, :bam, nil]
a2 = a.append(*a1).compact
a2 # => [:foo, "bar", 2, :baz, :bam]
Details:
- First method <tt>merge</tt> creates a copy of <tt>a</tt>,
appends (separately) each element of <tt>a1</tt> to the copy, and returns
[:foo, "bar", 2, :baz, nil, :bam, nil]
- Chained method <tt>compact</tt> creates a copy of that return value,
removes its <tt>nil</tt>-valued entries, and returns
[:foo, "bar", 2, :baz, :bam]
You can chain methods that are in different classes.
This example chains methods Hash#to_a and Array#reverse:
h = {foo: 0, bar: 1, baz: 2}
h.to_a.reverse # => [[:baz, 2], [:bar, 1], [:foo, 0]]
Details:
- First method Hash#to_a converts <tt>a</tt> to an \Array, and returns
[[:foo, 0], [:bar, 1], [:baz, 2]]
- Chained method Array#reverse creates copy of that return value,
reverses it, and returns
[[:baz, 2], [:bar, 1], [:foo, 0]]
=== Safe Navigation Operator
<code>&.</code>, called "safe navigation operator", allows to skip method call <code>&.</code>, called "safe navigation operator", allows to skip method call
when receiver is +nil+. It returns +nil+ and doesn't evaluate method's arguments when receiver is +nil+. It returns +nil+ and doesn't evaluate method's arguments