# class Array

An Array object is an ordered, integer-indexed collection of objects, called elements; the object represents an 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.

- Matrix.

- Heap.

- Hash table.

- Deque (double-ended queue).

- Queue.

- Stack.

There are also array-like data structures:

- Associative array (see `Hash`).

- Directory (see `Dir`).

- Environment (see `ENV`).

- Set (see `Set`).

- String (see `String`).

## Array Indexes¶ ↑

Array indexing starts at 0, as in C or Java.

A non-negative 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.

- …

### 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:

- Indexes 0 through 2 are in range.

- Index 3 is out of range.

A negative index is in range if and only 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.

### Effective Index¶ ↑

Although the effective index into an array is always an integer, some methods (both within class Array and elsewhere) accept one or more non-integer arguments that are integer-convertible objects.

## Creating Arrays¶ ↑

You can create an Array object explicitly with:

- An array literal:

      [1, 'one', :one, [2, 'two', :two]]

- A %w or %W string-array Literal:

      %w[foo bar baz] # => ["foo", "bar", "baz"]
      %w[1 % *]       # => ["1", "%", "*"]

- A %i or %I symbol-array Literal:

      %i[foo bar baz] # => [:foo, :bar, :baz]
      %i[1 % *]       # => [:"1", :%, :*]

- Method `Kernel#Array`:

      Array(["a", "b"])             # => ["a", "b"]
      Array(1..5)                   # => [1, 2, 3, 4, 5]
      Array(key: :value)            # => [[:key, :value]]
      Array(nil)                    # => []
      Array(1)                      # => [1]
      Array({:a => "a", :b => "b"}) # => [[:a, "a"], [:b, "b"]]

- Method `Array.new`:

      Array.new               # => []
      Array.new(3)            # => [nil, nil, nil]
      Array.new(4) {Hash.new} # => [{}, {}, {}, {}]
      Array.new(3, true)      # => [true, true, true]

  Note that the last example above populates the array with references to the same object. This is recommended only in cases where that object is a natively immutable object such as a symbol, a numeric, `nil`, `true`, or `false`.

  Another way to create an array with various objects, using a block; this usage is safe for mutable objects such as hashes, strings or other arrays:

      Array.new(4) {|i| i.to_s } # => ["0", "1", "2", "3"]

  Here is a way to create a multi-dimensional array:

      Array.new(3) {Array.new(3)}
      # => [[nil, nil, nil], [nil, nil, nil], [nil, nil, nil]]

A number of Ruby methods, both in the core and in the standard library, provide instance method `to_a`, which converts an object to an array.

- `ARGF#to_a`

- `Array#to_a`

- `Enumerable#to_a`

- `Hash#to_a`

- `MatchData#to_a`

- `NilClass#to_a`

- `OptionParser#to_a`

- `Range#to_a`

- `Set#to_a`

- `Struct#to_a`

- `Time#to_a`

- `Benchmark::Tms#to_a`

- CSV::Table#to_a

- `Enumerator::Lazy#to_a`

- Gem::List#to_a

- `Gem::NameTuple#to_a`

- `Gem::Platform#to_a`

- `Gem::RequestSet::Lockfile::Tokenizer#to_a`

- `Gem::SourceList#to_a`

- `OpenSSL::X509::Extension#to_a`

- `OpenSSL::X509::Name#to_a`

- Racc::ISet#to_a

- Rinda::RingFinger#to_a

- Ripper::Lexer::Elem#to_a

- `RubyVM::InstructionSequence#to_a`

- `YAML::DBM#to_a`

## 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 manipulating arrays.

Some of the more common ones are illustrated below.

## Accessing Elements¶ ↑

Elements in an array can be retrieved using the `Array#[]` method. It can take a single integer argument (a numeric index), a pair of arguments (start and length) or a range. Negative indices start counting from the end, with -1 being the last element.

    arr = [1, 2, 3, 4, 5, 6]
    arr[2]    #=> 3
    arr[100]  #=> nil
    arr[-3]   #=> 4
    arr[2, 3] #=> [3, 4, 5]
    arr[1..4] #=> [2, 3, 4, 5]
    arr[1..-3] #=> [2, 3, 4]

Another way to access a particular array element is by using the `at` method

    arr.at(0) #=> 1

The `slice` method works in an identical manner to `Array#[]`.

To raise an error for indices outside of the array bounds or else to provide a default value when that happens, you can use `fetch`.

    arr = ['a', 'b', 'c', 'd', 'e', 'f']
    arr.fetch(100) #=> IndexError: index 100 outside of array bounds: -6...6
    arr.fetch(100, "oops") #=> "oops"

The special methods `first` and `last` will return the first and last elements of an array, respectively.

    arr.first #=> 1
    arr.last  #=> 6

To return the first `n` elements of an array, use `take`

    arr.take(3) #=> [1, 2, 3]

`drop` does the opposite of `take`, by returning the elements after `n` elements have been dropped:

    arr.drop(3) #=> [4, 5, 6]

## 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`.

    browsers = ['Chrome', 'Firefox', 'Safari', 'Opera', 'IE']
    browsers.length #=> 5
    browsers.count #=> 5

To check whether an array contains any elements at all

    browsers.empty? #=> false

To check whether a particular item is included in the array

    browsers.include?('Konqueror') #=> false

## Adding Items to Arrays¶ ↑

Items can be added to the end of an array by using either `push` or `<<`

    arr = [1, 2, 3, 4]
    arr.push(5) #=> [1, 2, 3, 4, 5]
    arr << 6    #=> [1, 2, 3, 4, 5, 6]

`unshift` will add a new item to the beginning of an array.

    arr.unshift(0) #=> [0, 1, 2, 3, 4, 5, 6]

With `insert` you can add a new element to an array at any position.

    arr.insert(3, 'apple')  #=> [0, 1, 2, 'apple', 3, 4, 5, 6]

Using the `insert` method, you can also insert multiple values at once:

    arr.insert(3, 'orange', 'pear', 'grapefruit')
    #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6]

## Removing Items from an `Array`¶ ↑

The method `pop` removes the last element in an array and returns it:

    arr =  [1, 2, 3, 4, 5, 6]
    arr.pop #=> 6
    arr #=> [1, 2, 3, 4, 5]

To retrieve and at the same time remove the first item, use `shift`:

    arr.shift #=> 1
    arr #=> [2, 3, 4, 5]

To delete an element at a particular index:

    arr.delete_at(2) #=> 4
    arr #=> [2, 3, 5]

To delete a particular element anywhere in an array, use `delete`:

    arr = [1, 2, 2, 3]
    arr.delete(2) #=> 2
    arr #=> [1,3]

A useful method if you need to remove `nil` values from an array is `compact`:

    arr = ['foo', 0, nil, 'bar', 7, 'baz', nil]
    arr.compact  #=> ['foo', 0, 'bar', 7, 'baz']
    arr          #=> ['foo', 0, nil, 'bar', 7, 'baz', nil]
    arr.compact! #=> ['foo', 0, 'bar', 7, 'baz']
    arr          #=> ['foo', 0, 'bar', 7, 'baz']

Another common need is to remove duplicate elements from an array.

It has the non-destructive `uniq`, and destructive method `uniq!`

    arr = [2, 5, 6, 556, 6, 6, 8, 9, 0, 123, 556]
    arr.uniq #=> [2, 5, 6, 556, 8, 9, 0, 123]

## 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.

Note that this operation leaves the array unchanged.

    arr = [1, 2, 3, 4, 5]
    arr.each {|a| print a -= 10, " "}
    # prints: -9 -8 -7 -6 -5
    #=> [1, 2, 3, 4, 5]

Another sometimes useful iterator is `reverse_each` which will iterate over the elements in the array in reverse order.

    words = %w[first second third fourth fifth sixth]
    str = ""
    words.reverse_each {|word| str += "#{word} "}
    p str #=> "sixth fifth fourth third second first "

The `map` method can be used to create a new array based on the original array, but with the values modified by the supplied block:

    arr.map {|a| 2*a}     #=> [2, 4, 6, 8, 10]
    arr                   #=> [1, 2, 3, 4, 5]
    arr.map! {|a| a**2}   #=> [1, 4, 9, 16, 25]
    arr                   #=> [1, 4, 9, 16, 25]

## 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. While the destructive operations will modify the array they were called on, the non-destructive methods usually return a new array with the selected elements, but leave the original array unchanged.

### Non-destructive Selection¶ ↑

    arr = [1, 2, 3, 4, 5, 6]
    arr.select {|a| a > 3}       #=> [4, 5, 6]
    arr.reject {|a| a < 3}       #=> [3, 4, 5, 6]
    arr.drop_while {|a| a < 4}   #=> [4, 5, 6]
    arr                          #=> [1, 2, 3, 4, 5, 6]

### Destructive Selection¶ ↑

`select!` and `reject!` are the corresponding destructive methods to `select` and `reject`

Similar to `select` vs. `reject`, `delete_if` and `keep_if` have the exact opposite result when supplied with the same block:

    arr.delete_if {|a| a < 4}   #=> [4, 5, 6]
    arr                         #=> [4, 5, 6]

    arr = [1, 2, 3, 4, 5, 6]
    arr.keep_if {|a| a < 4}   #=> [1, 2, 3]
    arr                       #=> [1, 2, 3]

## What’s Here¶ ↑

First, what’s elsewhere. Class `Array`:

- Inherits from class Object.

- Includes module Enumerable, which provides dozens of additional methods.

Here, class `Array` provides methods that are useful for:

- Creating an Array

- Querying

- Comparing

- Fetching

- Assigning

- Deleting

- Combining

- Iterating

- Converting

- And more.…

### 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.

### Methods for Querying¶ ↑

- `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.

- `rindex`: Returns the index of the last element that meets a given criterion.

### Methods for Comparing¶ ↑

- `<=>`: 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.

- `eql?`: Returns whether each element in `self` is `eql?` to the corresponding element in a given object.

### Methods for Fetching¶ ↑

These methods do not modify `self`.

- `[]` (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 `<=>` or a given block.

- `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.

- `rassoc`: Returns the first element that is an array whose second element `==` a given object.

- `reject`: Returns an array containing elements not rejected by a given block.

- `reverse`: Returns all elements in reverse order.

- `rotate`: Returns all elements with some rotated from one end to the other.

- `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.

- `concat`: Appends all elements from given arrays.

- `fill`: Replaces specified elements with specified objects.

- `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 `<=>` 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`:

- `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!` (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.

### Methods for Combining¶ ↑

- `&`: Returns an array containing elements found both in `self` and a 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 element of `self` and all elements of a given array, 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¶ ↑

- `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¶ ↑

- `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`.

- `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.

### Other Methods¶ ↑

- `*`: Returns one of the following:

  - With integer argument `n`, a new array that is the concatenation of `n` copies of `self`.

  - With string argument `field_separator`, a new string that is equivalent to `join(field_separator)`.

- `pack`: Packs the elements into a binary sequence.

- `sum`: Returns a sum of elements according to either `+` or a given block.

### Public Class Methods

[] (*args)
Source

    static VALUE
    rb_ary_s_create(int argc, VALUE *argv, VALUE klass)
    {
        VALUE ary = ary_new(klass, argc);
        if (argc > 0 && argv) {
            ary_memcpy(ary, 0, argc, argv);
            ARY_SET_LEN(ary, argc);
        }

        return ary;
    }

Returns a new array, populated with the given objects:

    Array[1, 'a', /^A/]    # => [1, "a", /^A/]
    Array[]                # => []
    Array.[](1, 'a', /^A/) # => [1, "a", /^A/]

Related: see Methods for Creating an Array.

new → new_empty_array
new(array) → new_array
new(size, default_value = nil) → new_array
new(size = 0) {|index| ... } → new_array
Source

    static VALUE
    rb_ary_initialize(int argc, VALUE *argv, VALUE ary)
    {
        long len;
        VALUE size, val;

        rb_ary_modify(ary);
        if (argc == 0) {
            rb_ary_reset(ary);
            RUBY_ASSERT(ARY_EMBED_P(ary));
            RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0);
            if (rb_block_given_p()) {
                rb_warning("given block not used");
            }
            return ary;
        }
        rb_scan_args(argc, argv, "02", &size, &val);
        if (argc == 1 && !FIXNUM_P(size)) {
            val = rb_check_array_type(size);
            if (!NIL_P(val)) {
                rb_ary_replace(ary, val);
                return ary;
            }
        }

        len = NUM2LONG(size);
        /* NUM2LONG() may call size.to_int, ary can be frozen, modified, etc */
        if (len < 0) {
            rb_raise(rb_eArgError, "negative array size");
        }
        if (len > ARY_MAX_SIZE) {
            rb_raise(rb_eArgError, "array size too big");
        }
        /* recheck after argument conversion */
        rb_ary_modify(ary);
        ary_resize_capa(ary, len);
        if (rb_block_given_p()) {
            long i;

            if (argc == 2) {
                rb_warn("block supersedes default value argument");
            }
            for (i=0; i<len; i++) {
                rb_ary_store(ary, i, rb_yield(LONG2NUM(i)));
                ARY_SET_LEN(ary, i + 1);
            }
        }
        else {
            ary_memfill(ary, 0, len, val);
            ARY_SET_LEN(ary, len);
        }
        return ary;
    }

Returns a new array.

With no block and no argument given, returns a new empty array:

    Array.new # => []

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`:

    Array.new(0)    # => []
    Array.new(3)    # => [nil, nil, nil]
    Array.new(2, 3) # => [3, 3]

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:

    Array.new(3)  {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"]

A common pitfall for new Rubyists is providing an expression as `default_value`:

    array = Array.new(2, {})
    array # => [{}, {}]
    array[0][:a] = 1
    array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object

If you want the elements of the array to be distinct, you should pass a block:

    array = Array.new(2) { {} }
    array # => [{}, {}]
    array[0][:a] = 1
    array # => [{a: 1}, {}], as array[0] and array[1] are different objects

Raises `TypeError` if the first argument is not either an array or an integer-convertible object). Raises `ArgumentError` if the first argument is a negative integer.

Related: see Methods for Creating an Array.

try_convert(object) → object, new_array, or nil
Source

    static VALUE
    rb_ary_s_try_convert(VALUE dummy, VALUE ary)
    {
        return rb_check_array_type(ary);
    }

Attempts to return an array, based on the given `object`.

If `object` is an array, returns `object`.

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`.

Otherwise returns `nil`.

Related: see Methods for Creating an Array.

### Public Instance Methods

self & other_array → new_array
Source

    static VALUE
    rb_ary_and(VALUE ary1, VALUE ary2)
    {
        VALUE hash, ary3, v;
        st_data_t vv;
        long i;

        ary2 = to_ary(ary2);
        ary3 = rb_ary_new();
        if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return ary3;

        if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
            for (i=0; i<RARRAY_LEN(ary1); i++) {
                v = RARRAY_AREF(ary1, i);
                if (!rb_ary_includes_by_eql(ary2, v)) continue;
                if (rb_ary_includes_by_eql(ary3, v)) continue;
                rb_ary_push(ary3, v);
            }
            return ary3;
        }

        hash = ary_make_hash(ary2);

        for (i=0; i<RARRAY_LEN(ary1); i++) {
            v = RARRAY_AREF(ary1, i);
            vv = (st_data_t)v;
            if (rb_hash_stlike_delete(hash, &vv, 0)) {
                rb_ary_push(ary3, v);
            }
        }

        return ary3;
    }

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]

Omits duplicates:

    [0, 1, 1, 0] & [0, 1] # => [0, 1]

Preserves order from `self`:

    [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2]

Identifies common elements using method `eql?` (as defined in each element of `self`).

Related: see Methods for Combining.

self * n → new_array
self * string_separator → new_string
Source

    static VALUE
    rb_ary_times(VALUE ary, VALUE times)
    {
        VALUE ary2, tmp;
        const VALUE *ptr;
        long t, len;

        tmp = rb_check_string_type(times);
        if (!NIL_P(tmp)) {
            return rb_ary_join(ary, tmp);
        }

        len = NUM2LONG(times);
        if (len == 0) {
            ary2 = ary_new(rb_cArray, 0);
            goto out;
        }
        if (len < 0) {
            rb_raise(rb_eArgError, "negative argument");
        }
        if (ARY_MAX_SIZE/len < RARRAY_LEN(ary)) {
            rb_raise(rb_eArgError, "argument too big");
        }
        len *= RARRAY_LEN(ary);

        ary2 = ary_new(rb_cArray, len);
        ARY_SET_LEN(ary2, len);

        ptr = RARRAY_CONST_PTR(ary);
        t = RARRAY_LEN(ary);
        if (0 < t) {
            ary_memcpy(ary2, 0, t, ptr);
            while (t <= len/2) {
                ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2));
                t *= 2;
            }
            if (t < len) {
                ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2));
            }
        }
      out:
        return ary2;
    }

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 `self.join(string_separator)`:

    [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {foo: 0}"

self + other_array → new_array
Source

    VALUE
    rb_ary_plus(VALUE x, VALUE y)
    {
        VALUE z;
        long len, xlen, ylen;

        y = to_ary(y);
        xlen = RARRAY_LEN(x);
        ylen = RARRAY_LEN(y);
        len = xlen + ylen;
        z = rb_ary_new2(len);

        ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x));
        ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y));
        ARY_SET_LEN(z, len);
        return z;
    }

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: see Methods for Combining.

self - other_array → new_array
Source

    VALUE
    rb_ary_diff(VALUE ary1, VALUE ary2)
    {
        VALUE ary3;
        VALUE hash;
        long i;

        ary2 = to_ary(ary2);
        if (RARRAY_LEN(ary2) == 0) { return ary_make_shared_copy(ary1); }
        ary3 = rb_ary_new();

        if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN || RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
            for (i=0; i<RARRAY_LEN(ary1); i++) {
                VALUE elt = rb_ary_elt(ary1, i);
                if (rb_ary_includes_by_eql(ary2, elt)) continue;
                rb_ary_push(ary3, elt);
            }
            return ary3;
        }

        hash = ary_make_hash(ary2);
        for (i=0; i<RARRAY_LEN(ary1); i++) {
            if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue;
            rb_ary_push(ary3, rb_ary_elt(ary1, i));
        }

        return ary3;
    }

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]

Element are compared using method `eql?` (as defined in each element of `self`).

Related: see Methods for Combining.

self << object → self
Source

    VALUE
    rb_ary_push(VALUE ary, VALUE item)
    {
        long idx = RARRAY_LEN((ary_verify(ary), ary));
        VALUE target_ary = ary_ensure_room_for_push(ary, 1);
        RARRAY_PTR_USE(ary, ptr, {
            RB_OBJ_WRITE(target_ary, &ptr[idx], item);
        });
        ARY_SET_LEN(ary, idx + 1);
        ary_verify(ary);
        return ary;
    }

Appends `object` as the last element in `self`; returns `self`:

    [:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz]

Appends `object` as a single element, even if it is another array:

    [:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]]

Related: see Methods for Assigning.

self <=> other_array → -1, 0, or 1
Source

    VALUE
    rb_ary_cmp(VALUE ary1, VALUE ary2)
    {
        long len;
        VALUE v;

        ary2 = rb_check_array_type(ary2);
        if (NIL_P(ary2)) return Qnil;
        if (ary1 == ary2) return INT2FIX(0);
        v = rb_exec_recursive_paired(recursive_cmp, ary1, ary2, ary2);
        if (!UNDEF_P(v)) return v;
        len = RARRAY_LEN(ary1) - RARRAY_LEN(ary2);
        if (len == 0) return INT2FIX(0);
        if (len > 0) return INT2FIX(1);
        return INT2FIX(-1);
    }

Returns -1, 0, or 1 as `self` is determined to be less than, equal to, or greater than `other_array`.

Iterates over each index `i` in `(0...self.size)`:

- Computes `result[i]` as `self[i] <=> other_array[i]`.

- Immediately returns 1 if `result[i]` is 1:

      [0, 1, 2] <=> [0, 0, 2] # => 1

- Immediately returns -1 if `result[i]` is -1:

      [0, 1, 2] <=> [0, 2, 2] # => -1

- Continues if `result[i]` is 0.

When every `result` is 0, returns `self.size <=> other_array.size` (see `Integer#<=>`):

    [0, 1, 2] <=> [0, 1]        # => 1
    [0, 1, 2] <=> [0, 1, 2]     # => 0
    [0, 1, 2] <=> [0, 1, 2, 3]  # => -1

Note that when `other_array` is larger than `self`, its trailing elements do not affect the result:

    [0, 1, 2] <=> [0, 1, 2, -3] # => -1
    [0, 1, 2] <=> [0, 1, 2, 0]  # => -1
    [0, 1, 2] <=> [0, 1, 2, 3]  # => -1

Related: see Methods for Comparing.

self == other_array → true or false
Source

    static VALUE
    rb_ary_equal(VALUE ary1, VALUE ary2)
    {
        if (ary1 == ary2) return Qtrue;
        if (!RB_TYPE_P(ary2, T_ARRAY)) {
            if (!rb_respond_to(ary2, idTo_ary)) {
                return Qfalse;
            }
            return rb_equal(ary2, ary1);
        }
        if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
        if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
        return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2);
    }

Returns whether both:

- `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]`.

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.

self[index] → object or nil
self[start, length] → object or nil
self[range] → object or nil
self[aseq] → object or nil
Source

    VALUE
    rb_ary_aref(int argc, const VALUE *argv, VALUE ary)
    {
        rb_check_arity(argc, 1, 2);
        if (argc == 2) {
            return rb_ary_aref2(ary, argv[0], argv[1]);
        }
        return rb_ary_aref1(ary, argv[0]);
    }

Returns elements from `self`; does not modify `self`.

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]
    a[0] # => :foo
    a[2] # => 2
    a # => [:foo, "bar", 2]

If `index` is negative, counts backwards from the end of `self`:

    a = [:foo, 'bar', 2]
    a[-1] # => 2
    a[-2] # => "bar"

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`:

    a = [:foo, 'bar', 2]
    a[0, 2] # => [:foo, "bar"]
    a[1, 2] # => ["bar", 2]

If `start + length` is greater than `self.length`, returns all elements from offset `start` to the end:

    a = [:foo, 'bar', 2]
    a[0, 4] # => [:foo, "bar", 2]
    a[1, 3] # => ["bar", 2]
    a[2, 2] # => [2]

If `start == self.size` and `length >= 0`, returns a new empty `Array`.

If `length` is negative, returns `nil`.

When a single `Range` argument `range` is given, treats `range.min` as `start` above and `range.size` as `length` above:

    a = [:foo, 'bar', 2]
    a[0..1] # => [:foo, "bar"]
    a[1..2] # => ["bar", 2]

Special case: If `range.start == a.size`, returns a new empty `Array`.

If `range.end` is negative, calculates the end index from the end:

    a = [:foo, 'bar', 2]
    a[0..-1] # => [:foo, "bar", 2]
    a[0..-2] # => [:foo, "bar"]
    a[0..-3] # => [:foo]

If `range.start` is negative, calculates the start index from the end:

    a = [:foo, 'bar', 2]
    a[-1..2] # => [2]
    a[-2..2] # => ["bar", 2]
    a[-3..2] # => [:foo, "bar", 2]

If `range.start` is larger than the array size, returns `nil`.

    a = [:foo, 'bar', 2]
    a[4..1] # => nil
    a[4..0] # => nil
    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.

    a = ['--', 'data1', '--', 'data2', '--', 'data3']
    a[(1..).step(2)] # => ["data1", "data2", "data3"]

Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throws `RangeError`.

    a = ['--', 'data1', '--', 'data2', '--', 'data3']
    a[(1..11).step(2)]
    # RangeError (((1..11).step(2)) out of range)
    a[(7..).step(2)]
    # RangeError (((7..).step(2)) out of range)

If given a single argument, and its type is not one of the listed, tries to convert it to `Integer`, and raises if it is impossible:

    a = [:foo, 'bar', 2]
    # Raises TypeError (no implicit conversion of Symbol into Integer):
    a[:foo]

Related: see Methods for Fetching.

Also aliased as: slice
self[index] = object → object
self[start, length] = object → object
self[range] = object → object
Source

    static VALUE
    rb_ary_aset(int argc, VALUE *argv, VALUE ary)
    {
        long offset, beg, len;

        rb_check_arity(argc, 2, 3);
        rb_ary_modify_check(ary);
        if (argc == 3) {
            beg = NUM2LONG(argv[0]);
            len = NUM2LONG(argv[1]);
            return ary_aset_by_rb_ary_splice(ary, beg, len, argv[2]);
        }
        if (FIXNUM_P(argv[0])) {
            offset = FIX2LONG(argv[0]);
            return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
        }
        if (rb_range_beg_len(argv[0], &beg, &len, RARRAY_LEN(ary), 1)) {
            /* check if idx is Range */
            return ary_aset_by_rb_ary_splice(ary, beg, len, argv[1]);
        }

        offset = NUM2LONG(argv[0]);
        return ary_aset_by_rb_ary_store(ary, offset, argv[1]);
    }

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`.

If `index` is non-negative, assigns `object` the element at offset `index`:

    a = [:foo, 'bar', 2]
    a[0] = 'foo' # => "foo"
    a # => ["foo", "bar", 2]

If `index` is greater than `self.length`, extends the array:

    a = [:foo, 'bar', 2]
    a[7] = 'foo' # => "foo"
    a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"]

If `index` is negative, counts backwards from the end of the array:

    a = [:foo, 'bar', 2]
    a[-1] = 'two' # => "two"
    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`:

    a = [:foo, 'bar', 2]
    a[0, 2] = 'foo' # => "foo"
    a # => ["foo", 2]

If `start` is negative, counts backwards from the end of the array:

    a = [:foo, 'bar', 2]
    a[-2, 2] = 'foo' # => "foo"
    a # => [:foo, "foo"]

If `start` is non-negative and outside the array (`>= self.size`), extends the array with `nil`, assigns `object` at offset `start`, and ignores `length`:

    a = [:foo, 'bar', 2]
    a[6, 50] = 'foo' # => "foo"
    a # => [:foo, "bar", 2, nil, nil, nil, "foo"]

If `length` is zero, shifts elements at and following offset `start` and assigns `object` at offset `start`:

    a = [:foo, 'bar', 2]
    a[1, 0] = 'foo' # => "foo"
    a # => [:foo, "foo", "bar", 2]

If `length` is too large for the existing array, does not extend the array:

    a = [:foo, 'bar', 2]
    a[1, 5] = 'foo' # => "foo"
    a # => [:foo, "foo"]

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"
    a # => ["foo", 2]

if `range.begin` is negative, counts backwards from the end of the array:

    a = [:foo, 'bar', 2]
    a[-2..2] = 'foo' # => "foo"
    a # => [:foo, "foo"]

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"
    a # => [:foo, "bar", 2, nil, nil, nil, "foo"]

If `range.end` is zero, shifts elements at and following offset `start` and assigns `object` at offset `start`:

    a = [:foo, 'bar', 2]
    a[1..0] = 'foo' # => "foo"
    a # => [:foo, "foo", "bar", 2]

If `range.end` is negative, assigns `object` at offset `start`, retains `range.end.abs -1` elements past that, and removes those beyond:

    a = [:foo, 'bar', 2]
    a[1..-1] = 'foo' # => "foo"
    a # => [:foo, "foo"]
    a = [:foo, 'bar', 2]
    a[1..-2] = 'foo' # => "foo"
    a # => [:foo, "foo", 2]
    a = [:foo, 'bar', 2]
    a[1..-3] = 'foo' # => "foo"
    a # => [:foo, "foo", "bar", 2]
    a = [:foo, 'bar', 2]

If `range.end` is too large for the existing array, replaces array elements, but does not extend the array with `nil` values:

    a = [:foo, 'bar', 2]
    a[1..5] = 'foo' # => "foo"
    a # => [:foo, "foo"]

Related: see Methods for Assigning.

self | other_array → new_array
Source

    static VALUE
    rb_ary_or(VALUE ary1, VALUE ary2)
    {
        VALUE hash;

        ary2 = to_ary(ary2);
        if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
            VALUE ary3 = rb_ary_new();
            rb_ary_union(ary3, ary1);
            rb_ary_union(ary3, ary2);
            return ary3;
        }

        hash = ary_make_hash(ary1);
        rb_ary_union_hash(hash, ary2);

        return rb_hash_values(hash);
    }

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: see Methods for Combining.

all? → true or false
all?(object) → true or false
all? {|element| ... } → true or false
Source

    static VALUE
    rb_ary_all_p(int argc, VALUE *argv, VALUE ary)
    {
        long i, len = RARRAY_LEN(ary);

        rb_check_arity(argc, 0, 1);
        if (!len) return Qtrue;
        if (argc) {
            if (rb_block_given_p()) {
                rb_warn("given block not used");
            }
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (!RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
            }
        }
        else if (!rb_block_given_p()) {
            for (i = 0; i < len; ++i) {
                if (!RTEST(RARRAY_AREF(ary, i))) return Qfalse;
            }
        }
        else {
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
            }
        }
        return Qtrue;
    }

Returns whether for every element of `self`, a given criterion is satisfied.

With no block and no argument, returns whether every element of `self` is truthy:

    [[], {}, '', 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.

With argument `object` given, returns whether `object === ele` for every element `ele` in `self`:

    [0, 0, 0].all?(0)                    # => true
    [0, 1, 2].all?(1)                    # => false
    ['food', 'fool', 'foot'].all?(/foo/) # => true
    ['food', 'drink'].all?(/foo/)        # => false

With a block given, calls the block with each element in `self`; returns whether the block returns only truthy values:

    [0, 1, 2].all? { |ele| ele < 3 } # => true
    [0, 1, 2].all? { |ele| ele < 2 } # => false

With both a block and argument `object` given, ignores the block and uses `object` as above.

Special case: returns `true` if `self` is empty (regardless of any given argument or block).

Related: see Methods for Querying.

any? → true or false
any?(object) → true or false
any? {|element| ... } → true or false
Source

    static VALUE
    rb_ary_any_p(int argc, VALUE *argv, VALUE ary)
    {
        long i, len = RARRAY_LEN(ary);

        rb_check_arity(argc, 0, 1);
        if (!len) return Qfalse;
        if (argc) {
            if (rb_block_given_p()) {
                rb_warn("given block not used");
            }
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qtrue;
            }
        }
        else if (!rb_block_given_p()) {
            for (i = 0; i < len; ++i) {
                if (RTEST(RARRAY_AREF(ary, i))) return Qtrue;
            }
        }
        else {
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qtrue;
            }
        }
        return Qfalse;
    }

Returns whether for any element of `self`, a given criterion is satisfied.

With no block and no argument, returns whether any element of `self` is truthy:

    [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.

With argument `object` given, returns whether `object === ele` for any element `ele` in `self`:

    [nil, false, 0].any?(0)          # => true
    [nil, false, 1].any?(0)          # => false
    [nil, false, 'food'].any?(/foo/) # => true
    [nil, false, 'food'].any?(/bar/) # => false

With a block given, calls the block with each element in `self`; returns whether the block returns any truthy value:

    [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.

Special case: returns `false` if `self` is empty (regardless of any given argument or block).

Related: see Methods for Querying.

append(*objects) → 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]

Appends each argument as a single 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]]

Related: see Methods for Assigning.

Alias for: push
assoc(object) → found_array or nil
Source

    VALUE
    rb_ary_assoc(VALUE ary, VALUE key)
    {
        long i;
        VALUE v;

        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            v = rb_check_array_type(RARRAY_AREF(ary, i));
            if (!NIL_P(v) && RARRAY_LEN(v) > 0 &&
                rb_equal(RARRAY_AREF(v, 0), key))
                return v;
        }
        return Qnil;
    }

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: `Array#rassoc`; see also Methods for Fetching.

at(index) → object or nil
Source

    VALUE
    rb_ary_at(VALUE ary, VALUE pos)
    {
        return rb_ary_entry(ary, NUM2LONG(pos));
    }

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.

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(2.0) # => 2

For negative `index`, counts backwards from the end of `self`:

    a.at(-2) # => "bar"

Related: `Array#[]`; see also Methods for Fetching.

bsearch {|element| ... } → found_element or nil
bsearch → new_enumerator
Source

    static VALUE
    rb_ary_bsearch(VALUE ary)
    {
        VALUE index_result = rb_ary_bsearch_index(ary);

        if (FIXNUM_P(index_result)) {
            return rb_ary_entry(ary, FIX2LONG(index_result));
        }
        return index_result;
    }

Returns the element from `self` found by a binary search, or `nil` if the search found no suitable element.

See Binary Searching.

Related: see Methods for Fetching.

bsearch_index {|element| ... } → integer or nil
bsearch_index → new_enumerator
Source

    static VALUE
    rb_ary_bsearch_index(VALUE ary)
    {
        long low = 0, high = RARRAY_LEN(ary), mid;
        int smaller = 0, satisfied = 0;
        VALUE v, val;

        RETURN_ENUMERATOR(ary, 0, 0);
        while (low < high) {
            mid = low + ((high - low) / 2);
            val = rb_ary_entry(ary, mid);
            v = rb_yield(val);
            if (FIXNUM_P(v)) {
                if (v == INT2FIX(0)) return INT2FIX(mid);
                smaller = (SIGNED_VALUE)v < 0; /* Fixnum preserves its sign-bit */
            }
            else if (v == Qtrue) {
                satisfied = 1;
                smaller = 1;
            }
            else if (!RTEST(v)) {
                smaller = 0;
            }
            else if (rb_obj_is_kind_of(v, rb_cNumeric)) {
                const VALUE zero = INT2FIX(0);
                switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
                  case 0: return INT2FIX(mid);
                  case 1: smaller = 0; break;
                  case -1: smaller = 1;
                }
            }
            else {
                rb_raise(rb_eTypeError, "wrong argument type %"PRIsVALUE
                         " (must be numeric, true, false or nil)",
                         rb_obj_class(v));
            }
            if (smaller) {
                high = mid;
            }
            else {
                low = mid + 1;
            }
        }
        if (!satisfied) return Qnil;
        return INT2FIX(low);
    }

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.

Related: see Methods for Fetching.

clear → self
Source

    VALUE
    rb_ary_clear(VALUE ary)
    {
        rb_ary_modify_check(ary);
        if (ARY_SHARED_P(ary)) {
            rb_ary_unshare(ary);
            FL_SET_EMBED(ary);
            ARY_SET_EMBED_LEN(ary, 0);
        }
        else {
            ARY_SET_LEN(ary, 0);
            if (ARY_DEFAULT_SIZE * 2 < ARY_CAPA(ary)) {
                ary_resize_capa(ary, ARY_DEFAULT_SIZE * 2);
            }
        }
        ary_verify(ary);
        return ary;
    }

Removes all elements from `self`; returns `self`:

    a = [:foo, 'bar', 2]
    a.clear # => []

Related: see Methods for Deleting.

collect {|element| ... } → new_array
collect → new_enumerator
Source

    static VALUE
    rb_ary_collect(VALUE ary)
    {
        long i;
        VALUE collect;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        collect = rb_ary_new2(RARRAY_LEN(ary));
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_ary_push(collect, rb_yield(RARRAY_AREF(ary, i)));
        }
        return collect;
    }

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]

With no block given, returns a new `Enumerator`.

Related: `collect!`; see also Methods for Converting.

Also aliased as: map
collect! {|element| ... } → new_array
collect! → new_enumerator
Source

    static VALUE
    rb_ary_collect_bang(VALUE ary)
    {
        long i;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rb_ary_modify(ary);
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            rb_ary_store(ary, i, rb_yield(RARRAY_AREF(ary, i)));
        }
        return ary;
    }

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]

With no block given, returns a new `Enumerator`.

Related: `collect`; see also Methods for Converting.

Also aliased as: map!
combination(count) {|element| ... } → self
combination(count) → new_enumerator
Source

    static VALUE
    rb_ary_combination(VALUE ary, VALUE num)
    {
        long i, n, len;

        n = NUM2LONG(num);
        RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_combination_size);
        len = RARRAY_LEN(ary);
        if (n < 0 || len < n) {
            /* yield nothing */
        }
        else if (n == 0) {
            rb_yield(rb_ary_new2(0));
        }
        else if (n == 1) {
            for (i = 0; i < RARRAY_LEN(ary); i++) {
                rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
            }
        }
        else {
            VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
            volatile VALUE t0;
            long *stack = ALLOCV_N(long, t0, n+1);

            RBASIC_CLEAR_CLASS(ary0);
            combinate0(len, n, stack, ary0);
            ALLOCV_END(t0);
            RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
        }
        return ary;
    }

When a block and a positive integer-convertible object argument `count` (`0 < count <= self.size`) are given, calls the block with each combination of `self` of size `count`; returns `self`:

    a = %w[a b c]                                   # => ["a", "b", "c"]
    a.combination(2) {|combination| p combination } # => ["a", "b", "c"]

Output:

    ["a", "b"]
    ["a", "c"]
    ["b", "c"]

The order of the yielded combinations is not guaranteed.

When `count` is zero, calls the block once with a new empty array:

    a.combination(0) {|combination| p combination }
    [].combination(0) {|combination| p combination }

Output:

    []
    []

When `count` is negative or larger than `self.size` and `self` is non-empty, does not call the block:

    a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]
    a.combination(4)  {|combination| fail 'Cannot happen' } # => ["a", "b", "c"]

With no block given, returns a new `Enumerator`.

Related: `Array#permutation`; see also Methods for Iterating.

compact → new_array
Source

    static VALUE
    rb_ary_compact(VALUE ary)
    {
        ary = rb_ary_dup(ary);
        rb_ary_compact_bang(ary);
        return ary;
    }

Returns a new array containing only the non-`nil` elements from `self`; element order is preserved:

    a = [nil, 0, nil, false, nil, '', nil, [], nil, {}]
    a.compact # => [0, false, "", [], {}]

Related: `Array#compact!`; see also Methods for Deleting.

compact! → self or nil
Source

    static VALUE
    rb_ary_compact_bang(VALUE ary)
    {
        VALUE *p, *t, *end;
        long n;

        rb_ary_modify(ary);
        p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */
        end = p + RARRAY_LEN(ary);

        while (t < end) {
            if (NIL_P(*t)) t++;
            else *p++ = *t++;
        }
        n = p - RARRAY_CONST_PTR(ary);
        if (RARRAY_LEN(ary) == n) {
            return Qnil;
        }
        ary_resize_smaller(ary, n);

        return ary;
    }

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

Related: `Array#compact`; see also Methods for Deleting.

concat(*other_arrays) → self
Source

    static VALUE
    rb_ary_concat_multi(int argc, VALUE *argv, VALUE ary)
    {
        rb_ary_modify_check(ary);

        if (argc == 1) {
            rb_ary_concat(ary, argv[0]);
        }
        else if (argc > 1) {
            int i;
            VALUE args = rb_ary_hidden_new(argc);
            for (i = 0; i < argc; i++) {
                rb_ary_concat(args, argv[i]);
            }
            ary_append(ary, args);
        }

        ary_verify(ary);
        return ary;
    }

Adds to `self` all elements from each array in `other_arrays`; returns `self`:

    a = [0, 1]
    a.concat(['two', 'three'], [:four, :five], a)
    # => [0, 1, "two", "three", :four, :five, 0, 1]

Related: see Methods for Assigning.

count → integer
count(object) → integer
count {|element| ... } → integer
Source

    static VALUE
    rb_ary_count(int argc, VALUE *argv, VALUE ary)
    {
        long i, n = 0;

        if (rb_check_arity(argc, 0, 1) == 0) {
            VALUE v;

            if (!rb_block_given_p())
                return LONG2NUM(RARRAY_LEN(ary));

            for (i = 0; i < RARRAY_LEN(ary); i++) {
                v = RARRAY_AREF(ary, i);
                if (RTEST(rb_yield(v))) n++;
            }
        }
        else {
            VALUE obj = argv[0];

            if (rb_block_given_p()) {
                rb_warn("given block not used");
            }
            for (i = 0; i < RARRAY_LEN(ary); i++) {
                if (rb_equal(RARRAY_AREF(ary, i), obj)) n++;
            }
        }

        return LONG2NUM(n);
    }

Returns a count of specified elements.

With no argument and no block, returns the count of all elements:

    [0, :one, 'two', 3, 3.0].count # => 5

With argument `object` given, returns the count of elements `==` to `object`:

    [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

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.

cycle(count = nil) {|element| ... } → nil
cycle(count = nil) → new_enumerator
Source

    static VALUE
    rb_ary_cycle(int argc, VALUE *argv, VALUE ary)
    {
        long n, i;

        rb_check_arity(argc, 0, 1);

        RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_cycle_size);
        if (argc == 0 || NIL_P(argv[0])) {
            n = -1;
        }
        else {
            n = NUM2LONG(argv[0]);
            if (n <= 0) return Qnil;
        }

        while (RARRAY_LEN(ary) > 0 && (n < 0 || 0 < n--)) {
            for (i=0; i<RARRAY_LEN(ary); i++) {
                rb_yield(RARRAY_AREF(ary, i));
            }
        }
        return Qnil;
    }

With a block given, may call the block, depending on the value of argument `count`; `count` must be an integer-convertible object, 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]

When `count` is zero or negative, does not call the block:

    [0, 1].cycle(0) {|element| fail 'Cannot happen' }  # => nil
    [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil

When `count` is `nil`, cycles forever:

    # Prints 0 and 1 forever.
    [0, 1].cycle {|element| puts element }
    [0, 1].cycle(nil) {|element| puts element }

With no block given, returns a new `Enumerator`.

Related: see Methods for Iterating.

delete(object) → last_removed_object
delete(object) {|element| ... } → last_removed_object or block_return
Source

    VALUE
    rb_ary_delete(VALUE ary, VALUE item)
    {
        VALUE v = item;
        long i1, i2;

        for (i1 = i2 = 0; i1 < RARRAY_LEN(ary); i1++) {
            VALUE e = RARRAY_AREF(ary, i1);

            if (rb_equal(e, item)) {
                v = e;
                continue;
            }
            if (i1 != i2) {
                rb_ary_store(ary, i2, e);
            }
            i2++;
        }
        if (RARRAY_LEN(ary) == i2) {
            if (rb_block_given_p()) {
                return rb_yield(item);
            }
            return Qnil;
        }

        ary_resize_smaller(ary, i2);

        ary_verify(ary);
        return v;
    }

Removes zero or more elements from `self`.

With no block given, removes from `self` each element `ele` such that `ele == object`; returns the last removed element:

    a = [0, 1, 2, 2.0]
    a.delete(2) # => 2.0
    a           # => [0, 1]

Returns `nil` if no elements removed:

    a.delete(2) # => nil

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:

    a = [0, 1, 2, 2.0]
    a.delete(2) {|element| fail 'Cannot happen' } # => 2.0
    a                                             # => [0, 1]

If no such element is found, returns the block’s return value:

    a.delete(2) {|element| "Element #{element} not found." }
    # => "Element 2 not found."

Related: see Methods for Deleting.

delete_at(index) → removed_object or nil
Source

    static VALUE
    rb_ary_delete_at_m(VALUE ary, VALUE pos)
    {
        return rb_ary_delete_at(ary, NUM2LONG(pos));
    }

Removes the element of `self` at the given `index`, which must be an integer-convertible object.

When `index` is non-negative, deletes the element at offset `index`:

    a = [:foo, 'bar', 2]
    a.delete_at(1) # => "bar"
    a # => [:foo, 2]

When `index` is negative, counts backward from the end of the array:

    a = [:foo, 'bar', 2]
    a.delete_at(-2) # => "bar"
    a # => [:foo, 2]

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.

delete_if {|element| ... } → self
delete_if → new_numerator
Source

    static VALUE
    rb_ary_delete_if(VALUE ary)
    {
        ary_verify(ary);
        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        ary_reject_bang(ary);
        return ary;
    }

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]

With no block given, returns a new `Enumerator`.

Related: see Methods for Deleting.

difference(*other_arrays = []) → new_array
Source

    static VALUE
    rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary)
    {
        VALUE ary_diff;
        long i, length;
        volatile VALUE t0;
        bool *is_hash = ALLOCV_N(bool, t0, argc);
        ary_diff = rb_ary_new();
        length = RARRAY_LEN(ary);

        for (i = 0; i < argc; i++) {
            argv[i] = to_ary(argv[i]);
            is_hash[i] = (length > SMALL_ARRAY_LEN && RARRAY_LEN(argv[i]) > SMALL_ARRAY_LEN);
            if (is_hash[i]) argv[i] = ary_make_hash(argv[i]);
        }

        for (i = 0; i < RARRAY_LEN(ary); i++) {
            int j;
            VALUE elt = rb_ary_elt(ary, i);
            for (j = 0; j < argc; j++) {
                if (is_hash[j]) {
                    if (rb_hash_stlike_lookup(argv[j], RARRAY_AREF(ary, i), NULL))
                        break;
                }
                else {
                    if (rb_ary_includes_by_eql(argv[j], elt)) break;
                }
            }
            if (j == argc) rb_ary_push(ary_diff, elt);
        }

        ALLOCV_END(t0);

        return ary_diff;
    }

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].difference                        # => [0, 1, 2]

Returns a copy of `self` if no arguments are given.

Related: `Array#-`; see also Methods for Combining.

dig(index, *identifiers) → object
Source

    static VALUE
    rb_ary_dig(int argc, VALUE *argv, VALUE self)
    {
        rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
        self = rb_ary_at(self, *argv);
        if (!--argc) return self;
        ++argv;
        return rb_obj_dig(argc, argv, self, Qnil);
    }

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.

Examples:

    a = [:foo, [:bar, :baz, [:bat, :bam]]]
    a.dig(1) # => [:bar, :baz, [:bat, :bam]]
    a.dig(1, 2) # => [:bat, :bam]
    a.dig(1, 2, 0) # => :bat
    a.dig(1, 2, 3) # => nil

Related: see Methods for Fetching.

drop(count) → new_array
Source

    static VALUE
    rb_ary_drop(VALUE ary, VALUE n)
    {
        VALUE result;
        long pos = NUM2LONG(n);
        if (pos < 0) {
            rb_raise(rb_eArgError, "attempt to drop negative size");
        }

        result = rb_ary_subseq(ary, pos, RARRAY_LEN(ary));
        if (NIL_P(result)) result = rb_ary_new();
        return result;
    }

Returns a new array containing all but the first `count` element of `self`, where `count` is a non-negative integer; does not modify `self`.

Examples:

    a = [0, 1, 2, 3, 4, 5]
    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.

drop_while {|element| ... } → new_array
drop_while → new_enumerator
Source

    static VALUE
    rb_ary_drop_while(VALUE ary)
    {
        long i;

        RETURN_ENUMERATOR(ary, 0, 0);
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
        }
        return rb_ary_drop(ary, LONG2FIX(i));
    }

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; 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`.

Related: see Methods for Fetching.

each {|element| ... } → self
each → new_enumerator
Source

    VALUE
    rb_ary_each(VALUE ary)
    {
        long i;
        ary_verify(ary);
        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        for (i=0; i<RARRAY_LEN(ary); i++) {
            rb_yield(RARRAY_AREF(ary, i));
        }
        return ary;
    }

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}" }

Output:

    Symbol foo
    String bar
    Integer 2

Allows the array to be modified during iteration:

    a = [:foo, 'bar', 2]
    a.each {|element| puts element; a.clear if element.to_s.start_with?('b') }

Output:

    foo
    bar

With no block given, returns a new `Enumerator`.

Related: see Methods for Iterating.

each_index {|index| ... } → self
each_index → new_enumerator
Source

    static VALUE
    rb_ary_each_index(VALUE ary)
    {
        long i;
        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);

        for (i=0; i<RARRAY_LEN(ary); i++) {
            rb_yield(LONG2NUM(i));
        }
        return ary;
    }

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]}" }

Output:

    0 foo
    1 bar
    2 2

Allows the array to be modified during iteration:

    a = [:foo, 'bar', 2]
    a.each_index {|index| puts index; a.clear if index > 0 }
    a # => []

Output:

    0
    1

With no block given, returns a new `Enumerator`.

Related: see Methods for Iterating.

empty? → true or false
Source

    static VALUE
    rb_ary_empty_p(VALUE ary)
    {
        return RBOOL(RARRAY_LEN(ary) == 0);
    }

Returns `true` if the count of elements in `self` is zero, `false` otherwise.

Related: see Methods for Querying.

eql?(other_array) → true or false
Source

    static VALUE
    rb_ary_eql(VALUE ary1, VALUE ary2)
    {
        if (ary1 == ary2) return Qtrue;
        if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse;
        if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse;
        if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue;
        return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2);
    }

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])`:

    a0 = [:foo, 'bar', 2]
    a1 = [:foo, 'bar', 2]
    a1.eql?(a0) # => true

Otherwise, returns `false`.

This method is different from method `Array#==`, which compares using method `Object#==`.

Related: see Methods for Querying.

fetch(index) → element
fetch(index, default_value) → element or default_value
fetch(index) {|index| ... } → element or block_return_value
Source

    static VALUE
    rb_ary_fetch(int argc, VALUE *argv, VALUE ary)
    {
        VALUE pos, ifnone;
        long block_given;
        long idx;

        rb_scan_args(argc, argv, "11", &pos, &ifnone);
        block_given = rb_block_given_p();
        if (block_given && argc == 2) {
            rb_warn("block supersedes default value argument");
        }
        idx = NUM2LONG(pos);

        if (idx < 0) {
            idx +=  RARRAY_LEN(ary);
        }
        if (idx < 0 || RARRAY_LEN(ary) <= idx) {
            if (block_given) return rb_yield(pos);
            if (argc == 1) {
                rb_raise(rb_eIndexError, "index %ld outside of array bounds: %ld...%ld",
                            idx - (idx < 0 ? RARRAY_LEN(ary) : 0), -RARRAY_LEN(ary), RARRAY_LEN(ary));
            }
            return ifnone;
        }
        return RARRAY_AREF(ary, idx);
    }

Returns the element of `self` at offset `index` if `index` is in range; `index` must be an integer-convertible object.

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.1) # => "bar"

If `index` is negative, counts from the end of the array:

    a = [:foo, 'bar', 2]
    a.fetch(-1) # => 2
    a.fetch(-2) # => "bar"

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(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 with index and returns its return value:

    a = [:foo, 'bar', 2]
    a.fetch(1) {|index| raise 'Cannot happen' } # => "bar"
    a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50"

Related: see Methods for Fetching.

fetch_values(*indexes) → new_array
fetch_values(*indexes) { |index| ... } → new_array
Source

    # File array.rb, line 210
    def fetch_values(*indexes, &block)
      indexes.map! { |i| fetch(i, &block) }
      indexes
    end

With no block given, returns a new array containing the elements of `self` at the offsets specified by `indexes`. Each of the `indexes` must be an integer-convertible object:

    a = [:foo, :bar, :baz]
    a.fetch_values(2, 0)   # => [:baz, :foo]
    a.fetch_values(2.1, 0) # => [:baz, :foo]
    a.fetch_values         # => []

For a negative index, counts backwards from the end of the array:

    a.fetch_values(-2, -1) # [:bar, :baz]

When no block is given, raises an exception if any index is out of range.

With a block given, for each index:

- If the index is in range, uses an element of `self` (as above).

- Otherwise, calls the block with the index and uses the block’s return value.

Example:

    a = [:foo, :bar, :baz]
    a.fetch_values(1, 0, 42, 777) { |index| index.to_s }
    # => [:bar, :foo, "42", "777"]

Related: see Methods for Fetching.

fill(object, start = nil, count = nil) → new_array
fill(object, range) → new_array
fill(start = nil, count = nil) {|element| ... } → new_array
fill(range) {|element| ... } → new_array
Source

    static VALUE
    rb_ary_fill(int argc, VALUE *argv, VALUE ary)
    {
        VALUE item = Qundef, arg1, arg2;
        long beg = 0, end = 0, len = 0;

        if (rb_block_given_p()) {
            rb_scan_args(argc, argv, "02", &arg1, &arg2);
            argc += 1;              /* hackish */
        }
        else {
            rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
        }
        switch (argc) {
          case 1:
            beg = 0;
            len = RARRAY_LEN(ary);
            break;
          case 2:
            if (rb_range_beg_len(arg1, &beg, &len, RARRAY_LEN(ary), 1)) {
                break;
            }
            /* fall through */
          case 3:
            beg = NIL_P(arg1) ? 0 : NUM2LONG(arg1);
            if (beg < 0) {
                beg = RARRAY_LEN(ary) + beg;
                if (beg < 0) beg = 0;
            }
            len = NIL_P(arg2) ? RARRAY_LEN(ary) - beg : NUM2LONG(arg2);
            break;
        }
        rb_ary_modify(ary);
        if (len < 0) {
            return ary;
        }
        if (beg >= ARY_MAX_SIZE || len > ARY_MAX_SIZE - beg) {
            rb_raise(rb_eArgError, "argument too big");
        }
        end = beg + len;
        if (RARRAY_LEN(ary) < end) {
            if (end >= ARY_CAPA(ary)) {
                ary_resize_capa(ary, end);
            }
            ary_mem_clear(ary, RARRAY_LEN(ary), end - RARRAY_LEN(ary));
            ARY_SET_LEN(ary, end);
        }

        if (UNDEF_P(item)) {
            VALUE v;
            long i;

            for (i=beg; i<end; i++) {
                v = rb_yield(LONG2NUM(i));
                if (i>=RARRAY_LEN(ary)) break;
                ARY_SET(ary, i, v);
            }
        }
        else {
            ary_memfill(ary, beg, len, item);
        }
        return ary;
    }

Replaces selected elements in `self`; may add elements to `self`; always returns `self` (never a new array).

In brief:

    # 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"]

    # 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"]

    # 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"]

    # 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"]

    # 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"]

When arguments `start` and `count` are given, they select the elements of `self` to be replaced; each must be an integer-convertible object (or `nil`):

- `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.”

With argument `object` given, that one object is used for all replacements:

    o = Object.new           # => #<Object:0x0000014e7bff7600>
    a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"]
    a.fill(o, 1, 2)
    # => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "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:

    a = ['a', 'b', 'c', 'd']               # => ["a", "b", "c", "d"]
    a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"]

For arguments `start` and `count`:

- If `start` is non-negative, replaces `count` elements beginning at offset `start`:

      ['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", "-", "-"]

      ['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"]

  Extends `self` if necessary:

      ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"]
      ['a', 'b', 'c', 'd'].fill('-', 4, 2) # => ["a", "b", "c", "d", "-", "-"]

      ['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"]

  Fills with `nil` if necessary:

      ['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', '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"]

  Does nothing if `count` is non-positive:

      ['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"]

      ['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"]

- If `start` is negative, counts backwards from the end of `self`:

      ['a', 'b', 'c', 'd'].fill('-', -4, 3) # => ["-", "-", "-", "d"]
      ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"]

      ['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"]

  Extends `self` if necessary:

      ['a', 'b', 'c', 'd'].fill('-', -2, 3) # => ["a", "b", "-", "-", "-"]
      ['a', 'b', 'c', 'd'].fill('-', -1, 3) # => ["a", "b", "c", "-", "-", "-"]

      ['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"]

  Starts at the beginning of `self` if `start` is negative and out-of-range:

      ['a', 'b', 'c', 'd'].fill('-', -5, 2) # => ["-", "-", "c", "d"]
      ['a', 'b', 'c', 'd'].fill('-', -6, 2) # => ["-", "-", "c", "d"]

      ['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"]

  Does nothing if `count` is non-positive:

      ['a', 'b', 'c', 'd'].fill('-', -2, 0)  # => ["a", "b", "c", "d"]
      ['a', 'b', 'c', 'd'].fill('-', -2, -1) # => ["a", "b", "c", "d"]

      ['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"]

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 both `begin` and `end` are positive, they specify the first and last elements to be replaced:

      ['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 `end` is smaller than `begin`, replaces no elements:

      ['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 either is negative (or both are negative), counts backwards from the end of `self`:

      ['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"]

      ['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 `end` value is excluded (see `Range#exclude_end?`), omits the last replacement:

      ['a', 'b', 'c', 'd'].fill('-', 1...2)  # => ["a", "-", "c", "d"]
      ['a', 'b', 'c', 'd'].fill('-', 1...-2) # => ["a", "-", "c", "d"]

      ['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"]

- If the range is endless (see Endless Ranges), replaces elements to the end of `self`:

      ['a', 'b', 'c', 'd'].fill('-', 1..)          # => ["a", "-", "-", "-"]
      ['a', 'b', 'c', 'd'].fill(1..) {|e| e.to_s } # => ["a", "1", "2", "3"]

- If the range is beginless (see Beginless Ranges), replaces elements from the beginning of `self`:

      ['a', 'b', 'c', 'd'].fill('-', ..2)          # => ["-", "-", "-", "d"]
      ['a', 'b', 'c', 'd'].fill(..2) {|e| e.to_s } # => ["0", "1", "2", "d"]

Related: see Methods for Assigning.

filter {|element| ... } → new_array
filter → new_enumerator

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]
    a.select {|element| element.to_s.start_with?('b') }
    # => ["bar", :bam]

With no block given, returns a new `Enumerator`.

Related: see Methods for Fetching.

Alias for: select
filter! {|element| ... } → self or nil
filter! → new_enumerator

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:

    a = [:foo, 'bar', 2, :bam]
    a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]

Returns `nil` if no elements were removed.

With no block given, returns a new `Enumerator`.

Related: see Methods for Deleting.

Alias for: select!
find_index
Source
Also aliased as: index
first → object or nil
first(count) → new_array
Source

    # File array.rb, line 129
    def first n = unspecified = true
      if Primitive.mandatory_only?
        Primitive.attr! :leaf
        Primitive.cexpr! %q{ ary_first(self) }
      else
        if unspecified
          Primitive.cexpr! %q{ ary_first(self) }
        else
          Primitive.cexpr! %q{  ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_FIRST) }
        end
      end
    end

Returns elements from `self`, or `nil`; does not modify `self`.

With no argument given, returns the first element (if available):

    a = [:foo, 'bar', 2]
    a.first # => :foo
    a # => [:foo, "bar", 2]

If `self` is empty, returns `nil`.

    [].first # => nil

With a non-negative integer argument `count` given, returns the first `count` elements (as available) in a new array:

    a.first(0)  # => []
    a.first(2)  # => [:foo, "bar"]
    a.first(50) # => [:foo, "bar", 2]

Related: see Methods for Querying.

flatten(depth = nil) → new_array
Source

    static VALUE
    rb_ary_flatten(int argc, VALUE *argv, VALUE ary)
    {
        int level = -1;
        VALUE result;

        if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0])) {
            level = NUM2INT(argv[0]);
            if (level == 0) return ary_make_shared_copy(ary);
        }

        result = flatten(ary, level);
        if (result == ary) {
            result = ary_make_shared_copy(ary);
        }

        return result;
    }

Returns a new array that is a recursive flattening of `self` to `depth` levels of recursion; `depth` must be an integer-convertible object 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 `depth`, flattens recursively through `depth` levels:

    a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
    a              # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(0)   # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(1  ) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(2)   # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(3)   # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

With `nil` or negative `depth`, flattens all levels.

    a.flatten     # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Related: `Array#flatten!`; see also Methods for Converting.

flatten!(depth = nil) → self or nil
Source

    static VALUE
    rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
    {
        int mod = 0, level = -1;
        VALUE result, lv;

        lv = (rb_check_arity(argc, 0, 1) ? argv[0] : Qnil);
        rb_ary_modify_check(ary);
        if (!NIL_P(lv)) level = NUM2INT(lv);
        if (level == 0) return Qnil;

        result = flatten(ary, level);
        if (result == ary) {
            return Qnil;
        }
        if (!(mod = ARY_EMBED_P(result))) rb_ary_freeze(result);
        rb_ary_replace(ary, result);
        if (mod) ARY_SET_EMBED_LEN(result, 0);

        return ary;
    }

Returns `self` as a recursively flattening of `self` to `depth` levels of recursion; `depth` must be an integer-convertible object, 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`).

Returns `nil` if no elements were flattened.

With non-negative integer argument `depth`, flattens recursively through `depth` levels:

    a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ]
    a                   # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>]
    a.dup.flatten!(1)   # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.dup.flatten!(2)   # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.dup.flatten!(3)   # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

With `nil` or negative argument `depth`, flattens all levels:

    a.dup.flatten!     # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]
    a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>]

Related: `Array#flatten`; see also Methods for Assigning.

freeze → self
Source

    VALUE
    rb_ary_freeze(VALUE ary)
    {
        RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY));

        if (OBJ_FROZEN(ary)) return ary;

        if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) {
            ary_shrink_capa(ary);
        }

        return rb_obj_freeze(ary);
    }

Freezes `self` (if not already frozen); returns `self`:

    a = []
    a.frozen? # => false
    a.freeze
    a.frozen? # => true

No further changes may be made to `self`; raises `FrozenError` if a change is attempted.

Related: `Kernel#frozen?`.

hash → integer
Source

    static VALUE
    rb_ary_hash(VALUE ary)
    {
        return rb_ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary));
    }

Returns the integer hash value for `self`.

Two arrays with the same content will have the same hash value (and will compare using eql?):

    ['a', 'b'].hash == ['a', 'b'].hash # => true
    ['a', 'b'].hash == ['a', 'c'].hash # => false
    ['a', 'b'].hash == ['a'].hash      # => false

include?(object) → true or false
Source

    VALUE
    rb_ary_includes(VALUE ary, VALUE item)
    {
        long i;
        VALUE e;

        for (i=0; i<RARRAY_LEN(ary); i++) {
            e = RARRAY_AREF(ary, i);
            if (rb_equal(e, item)) {
                return Qtrue;
            }
        }
        return Qfalse;
    }

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

Related: see Methods for Querying.

index(object) → integer or nil
index {|element| ... } → integer or nil
index → new_enumerator

Returns the zero-based integer index of a specified element, or `nil`.

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.

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.

With neither an argument nor a block given, returns a new `Enumerator`.

Related: see Methods for Querying.

Alias for: find_index
initialize_copy(other_array) → self
Source

    VALUE
    rb_ary_replace(VALUE copy, VALUE orig)
    {
        rb_ary_modify_check(copy);
        orig = to_ary(orig);
        if (copy == orig) return copy;

        rb_ary_reset(copy);

        /* orig has enough space to embed the contents of orig. */
        if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) {
            RUBY_ASSERT(ARY_EMBED_P(copy));
            ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig));
            ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig));
        }
        /* orig is embedded but copy does not have enough space to embed the
         * contents of orig. */
        else if (ARY_EMBED_P(orig)) {
            long len = ARY_EMBED_LEN(orig);
            VALUE *ptr = ary_heap_alloc_buffer(len);

            FL_UNSET_EMBED(copy);
            ARY_SET_PTR(copy, ptr);
            ARY_SET_LEN(copy, len);
            ARY_SET_CAPA(copy, len);

            // No allocation and exception expected that could leave `copy` in a
            // bad state from the edits above.
            ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig));
        }
        /* Otherwise, orig is on heap and copy does not have enough space to embed
         * the contents of orig. */
        else {
            VALUE shared_root = ary_make_shared(orig);
            FL_UNSET_EMBED(copy);
            ARY_SET_PTR(copy, ARY_HEAP_PTR(orig));
            ARY_SET_LEN(copy, ARY_HEAP_LEN(orig));
            rb_ary_set_shared(copy, shared_root);
        }
        ary_verify(copy);
        return copy;
    }

Replaces the elements of `self` with the elements of `other_array`, which must be an array-convertible object; returns `self`:

    a = ['a', 'b', 'c']   # => ["a", "b", "c"]
    a.replace(['d', 'e']) # => ["d", "e"]

Related: see Methods for Assigning.

Also aliased as: replace
insert(index, *objects) → self
Source

    static VALUE
    rb_ary_insert(int argc, VALUE *argv, VALUE ary)
    {
        long pos;

        rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
        rb_ary_modify_check(ary);
        pos = NUM2LONG(argv[0]);
        if (argc == 1) return ary;
        if (pos == -1) {
            pos = RARRAY_LEN(ary);
        }
        else if (pos < 0) {
            long minpos = -RARRAY_LEN(ary) - 1;
            if (pos < minpos) {
                rb_raise(rb_eIndexError, "index %ld too small for array; minimum: %ld",
                         pos, minpos);
            }
            pos++;
        }
        rb_ary_splice(ary, pos, 0, argv + 1, argc - 1);
        return ary;
    }

Inserts the given `objects` as elements of `self`; returns `self`.

When `index` is non-negative, inserts `objects` before the element at offset `index`:

    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 = ['a', 'b', 'c']     # => ["a", "b", "c"]
    a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z]

When `index` is negative, inserts `objects` after the element at offset `index + self.size`:

    a = ['a', 'b', 'c']      # => ["a", "b", "c"]
    a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"]

With no `objects` given, does nothing:

    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.

inspect → new_string
Source

    static VALUE
    rb_ary_inspect(VALUE ary)
    {
        if (RARRAY_LEN(ary) == 0) return rb_usascii_str_new2("[]");
        return rb_exec_recursive(inspect_ary, ary, 0);
    }

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.

Also aliased as: to_s
intersect?(other_array) → true or false
Source

    static VALUE
    rb_ary_intersect_p(VALUE ary1, VALUE ary2)
    {
        VALUE hash, v, result, shorter, longer;
        st_data_t vv;
        long i;

        ary2 = to_ary(ary2);
        if (RARRAY_LEN(ary1) == 0 || RARRAY_LEN(ary2) == 0) return Qfalse;

        if (RARRAY_LEN(ary1) <= SMALL_ARRAY_LEN && RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) {
            for (i=0; i<RARRAY_LEN(ary1); i++) {
                v = RARRAY_AREF(ary1, i);
                if (rb_ary_includes_by_eql(ary2, v)) return Qtrue;
            }
            return Qfalse;
        }

        shorter = ary1;
        longer = ary2;
        if (RARRAY_LEN(ary1) > RARRAY_LEN(ary2)) {
            longer = ary1;
            shorter = ary2;
        }

        hash = ary_make_hash(shorter);
        result = Qfalse;

        for (i=0; i<RARRAY_LEN(longer); i++) {
            v = RARRAY_AREF(longer, i);
            vv = (st_data_t)v;
            if (rb_hash_stlike_lookup(hash, vv, 0)) {
                result = Qtrue;
                break;
            }
        }

        return result;
    }

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

Each element must correctly implement method `hash`.

Related: see Methods for Querying.

intersection(*other_arrays) → new_array
Source

    static VALUE
    rb_ary_intersection_multi(int argc, VALUE *argv, VALUE ary)
    {
        VALUE result = rb_ary_dup(ary);
        int i;

        for (i = 0; i < argc; i++) {
            result = rb_ary_and(result, argv[i]);
        }

        return result;
    }

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, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1]

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 are given.

Related: see Methods for Combining.

join(separator = $,) → new_string
Source

    static VALUE
    rb_ary_join_m(int argc, VALUE *argv, VALUE ary)
    {
        VALUE sep;

        if (rb_check_arity(argc, 0, 1) == 0 || NIL_P(sep = argv[0])) {
            sep = rb_output_fs;
            if (!NIL_P(sep)) {
                rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "$, is set to non-nil value");
            }
        }

        return rb_ary_join(ary, sep);
    }

Returns the new string formed by joining the converted elements of `self`; for each element `element`:

- Converts recursively using `element.join(separator)` if `element` is a `kind_of?(Array)`.

- Otherwise, converts using `element.to_s`.

With no argument given, joins using the output field separator, `$,`:

    a = [:foo, 'bar', 2]
    $, # => nil
    a.join # => "foobar2"

With string argument `separator` given, joins using that separator:

    a = [:foo, 'bar', 2]
    a.join("\n") # => "foo\nbar\n2"

Joins recursively for nested arrays:

    a = [:foo, [:bar, [:baz, :bat]]]
    a.join # => "foobarbazbat"

Related: see Methods for Converting.

keep_if {|element| ... } → self
keep_if → new_enumerator
Source

    static VALUE
    rb_ary_keep_if(VALUE ary)
    {
        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rb_ary_select_bang(ary);
        return ary;
    }

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]

With no block given, returns a new `Enumerator`.

Related: see Methods for Deleting.

last → last_object or nil
last(count) → new_array
Source

    # File array.rb, line 166
    def last n = unspecified = true
      if Primitive.mandatory_only?
        Primitive.attr! :leaf
        Primitive.cexpr! %q{ ary_last(self) }
      else
        if unspecified
          Primitive.cexpr! %q{ ary_last(self) }
        else
          Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_LAST) }
        end
      end
    end

Returns elements from `self`, or `nil`; `self` is not modified.

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

With non-negative integer argument `count` given, returns a new array containing the trailing `count` 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) # => []

Related: see Methods for Fetching.

length → integer
Source

    static VALUE
    rb_ary_length(VALUE ary)
    {
        long len = RARRAY_LEN(ary);
        return LONG2NUM(len);
    }

Returns the count of elements in `self`:

    [0, 1, 2].length # => 3
    [].length        # => 0

Related: see Methods for Querying.

Also aliased as: size
map {|element| ... } → new_array
map → new_enumerator

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]

With no block given, returns a new `Enumerator`.

Related: `collect!`; see also Methods for Converting.

Also aliased as: collect
Alias for: collect
map! {|element| ... } → new_array
map! → new_enumerator

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]

With no block given, returns a new `Enumerator`.

Related: `collect`; see also Methods for Converting.

Alias for: collect!
max → element
max(count) → new_array
max {|a, b| ... } → element
max(count) {|a, b| ... } → new_array
Source

    static VALUE
    rb_ary_max(int argc, VALUE *argv, VALUE ary)
    {
        VALUE result = Qundef, v;
        VALUE num;
        long i;

        if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
           return rb_nmin_run(ary, num, 0, 1, 1);

        const long n = RARRAY_LEN(ary);
        if (rb_block_given_p()) {
            for (i = 0; i < RARRAY_LEN(ary); i++) {
               v = RARRAY_AREF(ary, i);
               if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) > 0) {
                   result = v;
               }
            }
        }
        else if (n > 0) {
            result = RARRAY_AREF(ary, 0);
            if (n > 1) {
                if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
                    return ary_max_opt_fixnum(ary, 1, result);
                }
                else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
                    return ary_max_opt_string(ary, 1, result);
                }
                else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
                    return ary_max_opt_float(ary, 1, result);
                }
                else {
                    return ary_max_generic(ary, 1, result);
                }
            }
        }
        if (UNDEF_P(result)) return Qnil;
        return result;
    }

Returns one of the following:

- The maximum-valued element from `self`.

- A new array of maximum-valued elements from `self`.

Does not modify `self`.

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 `<=>`:

    [1, 0, 3, 2].max # => 3

With non-negative numeric argument `count` and no block, returns a new array with at most `count` elements, in descending order, per method `<=>`:

    [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)   # => []

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 elements; returns the element having the maximum value per the block:

    ['0', '', '000', '00'].max {|a, b| a.size <=> b.size }
    # => "000"

With non-negative numeric argument `count` and a block, returns a new array with at most `count` elements, in descending order, per the block:

    ['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size }
    # => ["000", "00"]

Related: see Methods for Fetching.

min → element
min(count) → new_array
min {|a, b| ... } → element
min(count) {|a, b| ... } → new_array
Source

    static VALUE
    rb_ary_min(int argc, VALUE *argv, VALUE ary)
    {
        VALUE result = Qundef, v;
        VALUE num;
        long i;

        if (rb_check_arity(argc, 0, 1) && !NIL_P(num = argv[0]))
           return rb_nmin_run(ary, num, 0, 0, 1);

        const long n = RARRAY_LEN(ary);
        if (rb_block_given_p()) {
            for (i = 0; i < RARRAY_LEN(ary); i++) {
               v = RARRAY_AREF(ary, i);
               if (UNDEF_P(result) || rb_cmpint(rb_yield_values(2, v, result), v, result) < 0) {
                   result = v;
               }
            }
        }
        else if (n > 0) {
            result = RARRAY_AREF(ary, 0);
            if (n > 1) {
                if (FIXNUM_P(result) && CMP_OPTIMIZABLE(INTEGER)) {
                    return ary_min_opt_fixnum(ary, 1, result);
                }
                else if (STRING_P(result) && CMP_OPTIMIZABLE(STRING)) {
                    return ary_min_opt_string(ary, 1, result);
                }
                else if (RB_FLOAT_TYPE_P(result) && CMP_OPTIMIZABLE(FLOAT)) {
                    return ary_min_opt_float(ary, 1, result);
                }
                else {
                    return ary_min_generic(ary, 1, result);
                }
            }
        }
        if (UNDEF_P(result)) return Qnil;
        return result;
    }

Returns one of the following:

- The minimum-valued element from `self`.

- A new array of minimum-valued elements from `self`.

Does not modify `self`.

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 `<=>`:

    [1, 0, 3, 2].min # => 0

With non-negative numeric argument `count` and no block, returns a new array with at most `count` elements, in ascending order, per method `<=>`:

    [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)   # => []

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 elements; returns the element having the minimum value per the block:

    ['0', '', '000', '00'].min {|a, b| a.size <=> b.size }
    # => ""

With non-negative numeric argument `count` and a block, returns a new array with at most `count` elements, in ascending order, per the block:

    ['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size }
    # => ["", "0"]

Related: see Methods for Fetching.

minmax → array
minmax {|a, b| ... } → array
Source

    static VALUE
    rb_ary_minmax(VALUE ary)
    {
        if (rb_block_given_p()) {
            return rb_call_super(0, NULL);
        }
        return rb_assoc_new(rb_ary_min(0, 0, ary), rb_ary_max(0, 0, ary));
    }

Returns a 2-element array containing the minimum-valued and maximum-valued elements from `self`; does not modify `self`.

With no block given, the minimum and maximum values are determined using method `<=>`:

    [1, 0, 3, 2].minmax # => [0, 3]

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', '', '000', '00'].minmax {|a, b| a.size <=> b.size }
    # => ["", "000"]

Related: see Methods for Fetching.

none? → true or false
none?(object) → true or false
none? {|element| ... } → true or false
Source

    static VALUE
    rb_ary_none_p(int argc, VALUE *argv, VALUE ary)
    {
        long i, len = RARRAY_LEN(ary);

        rb_check_arity(argc, 0, 1);
        if (!len) return Qtrue;
        if (argc) {
            if (rb_block_given_p()) {
                rb_warn("given block not used");
            }
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) return Qfalse;
            }
        }
        else if (!rb_block_given_p()) {
            for (i = 0; i < len; ++i) {
                if (RTEST(RARRAY_AREF(ary, i))) return Qfalse;
            }
        }
        else {
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) return Qfalse;
            }
        }
        return Qtrue;
    }

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, 0, false].none? # => false
    [].none?              # => true

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

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: see Methods for Querying.

one? → true or false
one? {|element| ... } → true or false
one?(object) → true or false
Source

    static VALUE
    rb_ary_one_p(int argc, VALUE *argv, VALUE ary)
    {
        long i, len = RARRAY_LEN(ary);
        VALUE result = Qfalse;

        rb_check_arity(argc, 0, 1);
        if (!len) return Qfalse;
        if (argc) {
            if (rb_block_given_p()) {
                rb_warn("given block not used");
            }
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_funcall(argv[0], idEqq, 1, RARRAY_AREF(ary, i)))) {
                    if (result) return Qfalse;
                    result = Qtrue;
                }
            }
        }
        else if (!rb_block_given_p()) {
            for (i = 0; i < len; ++i) {
                if (RTEST(RARRAY_AREF(ary, i))) {
                    if (result) return Qfalse;
                    result = Qtrue;
                }
            }
        }
        else {
            for (i = 0; i < RARRAY_LEN(ary); ++i) {
                if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
                    if (result) return Qfalse;
                    result = Qtrue;
                }
            }
        }
        return result;
    }

Returns `true` if exactly one element of `self` meets a given criterion.

With no block given and no argument, returns `true` if `self` has exactly one truthy element, `false` otherwise:

    [nil, 0].one? # => true
    [0, 0].one? # => false
    [nil, nil].one? # => false
    [].one? # => false

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

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
    [1, 1, 2].one?(0) # => false
    ['food', 'drink'].one?(/bar/) # => false
    ['food', 'drink'].one?(/foo/) # => true
    [].one?(/foo/) # => false

Related: see Methods for Querying.

pack(template, buffer: nil) → string
Source

    # File pack.rb, line 7
    def pack(fmt, buffer: nil)
      Primitive.pack_pack(fmt, buffer)
    end

Formats each element in `self` into a binary string; returns that string. See Packed Data.

permutation(count = self.size) {|permutation| ... } → self
permutation(count = self.size) → new_enumerator
Source

    static VALUE
    rb_ary_permutation(int argc, VALUE *argv, VALUE ary)
    {
        long r, n, i;

        n = RARRAY_LEN(ary);                  /* Array length */
        RETURN_SIZED_ENUMERATOR(ary, argc, argv, rb_ary_permutation_size);   /* Return enumerator if no block */
        r = n;
        if (rb_check_arity(argc, 0, 1) && !NIL_P(argv[0]))
            r = NUM2LONG(argv[0]);            /* Permutation size from argument */

        if (r < 0 || n < r) {
            /* no permutations: yield nothing */
        }
        else if (r == 0) { /* exactly one permutation: the zero-length array */
            rb_yield(rb_ary_new2(0));
        }
        else if (r == 1) { /* this is a special, easy case */
            for (i = 0; i < RARRAY_LEN(ary); i++) {
                rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
            }
        }
        else {             /* this is the general case */
            volatile VALUE t0;
            long *p = ALLOCV_N(long, t0, r+roomof(n, sizeof(long)));
            char *used = (char*)(p + r);
            VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
            RBASIC_CLEAR_CLASS(ary0);

            MEMZERO(used, char, n); /* initialize array */

            permute0(n, r, p, used, ary0); /* compute and yield permutations */
            ALLOCV_END(t0);
            RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
        }
        return ary;
    }

Iterates over permutations of the elements of `self`; the order of permutations is indeterminate.

With a block and an in-range positive integer argument `count` (`0 < count <= self.size`) given, calls the block with each permutation of `self` of size `count`; returns `self`:

    a = [0, 1, 2]
    perms = []
    a.permutation(1) {|perm| perms.push(perm) }
    perms # => [[0], [1], [2]]

    perms = []
    a.permutation(2) {|perm| perms.push(perm) }
    perms # => [[0, 1], [0, 2], [1, 0], [1, 2], [2, 0], [2, 1]]

    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]]

When `count` is zero, calls the block once with a new empty array:

    perms = []
    a.permutation(0) {|perm| perms.push(perm) }
    perms # => [[]]

When `count` is out of range (negative or larger than `self.size`), does not call the block:

    a.permutation(-1) {|permutation| fail 'Cannot happen' }
    a.permutation(4) {|permutation| fail 'Cannot happen' }

With no block given, returns a new `Enumerator`.

Related: Methods for Iterating.

pop → object or nil
pop(count) → new_array
Source

    static VALUE
    rb_ary_pop_m(int argc, VALUE *argv, VALUE ary)
    {
        VALUE result;

        if (argc == 0) {
            return rb_ary_pop(ary);
        }

        rb_ary_modify_check(ary);
        result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST);
        ARY_INCREASE_LEN(ary, -RARRAY_LEN(result));
        ary_verify(ary);
        return result;
    }

Removes and returns trailing elements of `self`.

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"]
    [].pop # => nil

With non-negative integer argument `count` given, returns a new array containing the trailing `count` elements of `self`, as available:

    a = [:foo, 'bar', 2]
    a.pop(2) # => ["bar", 2]
    a        # => [:foo]

    a = [:foo, 'bar', 2]
    a.pop(50) # => [:foo, "bar", 2]
    a         # => []

Related: `Array#push`; see also Methods for Deleting.

prepend(*objects) → self

Prepends the given `objects` to `self`:

    a = [:foo, 'bar', 2]
    a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]

Related: `Array#shift`; see also Methods for Assigning.

Alias for: unshift
product(*other_arrays) → new_array
product(*other_arrays) {|combination| ... } → self
Source

    static VALUE
    rb_ary_product(int argc, VALUE *argv, VALUE ary)
    {
        int n = argc+1;    /* How many arrays we're operating on */
        volatile VALUE t0 = rb_ary_hidden_new(n);
        volatile VALUE t1 = Qundef;
        VALUE *arrays = RARRAY_PTR(t0); /* The arrays we're computing the product of */
        int *counters = ALLOCV_N(int, t1, n); /* The current position in each one */
        VALUE result = Qnil;      /* The array we'll be returning, when no block given */
        long i,j;
        long resultlen = 1;

        RBASIC_CLEAR_CLASS(t0);

        /* initialize the arrays of arrays */
        ARY_SET_LEN(t0, n);
        arrays[0] = ary;
        for (i = 1; i < n; i++) arrays[i] = Qnil;
        for (i = 1; i < n; i++) arrays[i] = to_ary(argv[i-1]);

        /* initialize the counters for the arrays */
        for (i = 0; i < n; i++) counters[i] = 0;

        /* Otherwise, allocate and fill in an array of results */
        if (rb_block_given_p()) {
            /* Make defensive copies of arrays; exit if any is empty */
            for (i = 0; i < n; i++) {
                if (RARRAY_LEN(arrays[i]) == 0) goto done;
                arrays[i] = ary_make_shared_copy(arrays[i]);
            }
        }
        else {
            /* Compute the length of the result array; return [] if any is empty */
            for (i = 0; i < n; i++) {
                long k = RARRAY_LEN(arrays[i]);
                if (k == 0) {
                    result = rb_ary_new2(0);
                    goto done;
                }
                if (MUL_OVERFLOW_LONG_P(resultlen, k))
                    rb_raise(rb_eRangeError, "too big to product");
                resultlen *= k;
            }
            result = rb_ary_new2(resultlen);
        }
        for (;;) {
            int m;
            /* fill in one subarray */
            VALUE subarray = rb_ary_new2(n);
            for (j = 0; j < n; j++) {
                rb_ary_push(subarray, rb_ary_entry(arrays[j], counters[j]));
            }

            /* put it on the result array */
            if (NIL_P(result)) {
                FL_SET(t0, RARRAY_SHARED_ROOT_FLAG);
                rb_yield(subarray);
                if (!FL_TEST(t0, RARRAY_SHARED_ROOT_FLAG)) {
                    rb_raise(rb_eRuntimeError, "product reentered");
                }
                else {
                    FL_UNSET(t0, RARRAY_SHARED_ROOT_FLAG);
                }
            }
            else {
                rb_ary_push(result, subarray);
            }

            /*
             * Increment the last counter.  If it overflows, reset to 0
             * and increment the one before it.
             */
            m = n-1;
            counters[m]++;
            while (counters[m] == RARRAY_LEN(arrays[m])) {
                counters[m] = 0;
                /* If the first counter overflows, we are done */
                if (--m < 0) goto done;
                counters[m]++;
            }
        }

    done:
        ALLOCV_END(t1);

        return NIL_P(result) ? ary : result;
    }

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.

With no block given, returns the combinations as an array of arrays:

    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

If `self` or any argument is empty, returns an empty array:

    [].product([2, 3], [4, 5]) # => []
    [0, 1].product([2, 3], []) # => []

If no argument is given, returns an array of 1-element arrays, each containing an element of `self`:

    a.product # => [[0], [1], [2]]

With a block given, calls the block with each combination; returns `self`:

    p = []
    [0, 1].product([2, 3]) {|combination| p.push(combination) }
    p # => [[0, 2], [0, 3], [1, 2], [1, 3]]

If `self` or any argument is empty, does not call the block:

    [].product([2, 3], [4, 5]) {|combination| fail 'Cannot happen' }
    # => []
    [0, 1].product([2, 3], []) {|combination| fail 'Cannot happen' }
    # => [0, 1]

If no argument is given, calls the block with each element of `self` as a 1-element array:

    p = []
    [0, 1].product {|combination| p.push(combination) }
    p # => [[0], [1]]

Related: see Methods for Combining.

push(*objects) → self
Source

    static VALUE
    rb_ary_push_m(int argc, VALUE *argv, VALUE ary)
    {
        return rb_ary_cat(ary, argv, argc);
    }

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]

Appends each argument as a single 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]]

Related: see Methods for Assigning.

Also aliased as: append
rassoc(object) → found_array or nil
Source

    VALUE
    rb_ary_rassoc(VALUE ary, VALUE value)
    {
        long i;
        VALUE v;

        for (i = 0; i < RARRAY_LEN(ary); ++i) {
            v = rb_check_array_type(RARRAY_AREF(ary, i));
            if (RB_TYPE_P(v, T_ARRAY) &&
                RARRAY_LEN(v) > 1 &&
                rb_equal(RARRAY_AREF(v, 1), value))
                return v;
        }
        return Qnil;
    }

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: `Array#assoc`; see also Methods for Fetching.

reject {|element| ... } → new_array
reject → new_enumerator
Source

    static VALUE
    rb_ary_reject(VALUE ary)
    {
        VALUE rejected_ary;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rejected_ary = rb_ary_new();
        ary_reject(ary, rejected_ary);
        return rejected_ary;
    }

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]

With no block given, returns a new `Enumerator`.

Related: Methods for Fetching.

reject! {|element| ... } → self or nil
reject! → new_enumerator
Source

    static VALUE
    rb_ary_reject_bang(VALUE ary)
    {
        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rb_ary_modify(ary);
        return ary_reject_bang(ary);
    }

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:

    a = [:foo, 'bar', 2, 'bat']
    a.reject! {|element| element.to_s.start_with?('b') } # => [:foo, 2]

Returns `nil` if no elements removed.

With no block given, returns a new `Enumerator`.

Related: see Methods for Deleting.

repeated_combination(size) {|combination| ... } → self
repeated_combination(size) → new_enumerator
Source

    static VALUE
    rb_ary_repeated_combination(VALUE ary, VALUE num)
    {
        long n, i, len;

        n = NUM2LONG(num);                 /* Combination size from argument */
        RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_combination_size);   /* Return enumerator if no block */
        len = RARRAY_LEN(ary);
        if (n < 0) {
            /* yield nothing */
        }
        else if (n == 0) {
            rb_yield(rb_ary_new2(0));
        }
        else if (n == 1) {
            for (i = 0; i < RARRAY_LEN(ary); i++) {
                rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
            }
        }
        else if (len == 0) {
            /* yield nothing */
        }
        else {
            volatile VALUE t0;
            long *p = ALLOCV_N(long, t0, n);
            VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
            RBASIC_CLEAR_CLASS(ary0);

            rcombinate0(len, n, p, n, ary0); /* compute and yield repeated combinations */
            ALLOCV_END(t0);
            RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
        }
        return ary;
    }

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.

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`.

Examples:

- `size` is 1:

      c = []
      [0, 1, 2].repeated_combination(1) {|combination| c.push(combination) }
      c # => [[0], [1], [2]]

- `size` is 2:

      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 `size` is zero, calls the block once with an empty array.

If `size` is negative, does not call the block:

    [0, 1, 2].repeated_combination(-1) {|combination| fail 'Cannot happen' }

With no block given, returns a new `Enumerator`.

Related: see Methods for Combining.

repeated_permutation(size) {|permutation| ... } → self
repeated_permutation(size) → new_enumerator
Source

    static VALUE
    rb_ary_repeated_permutation(VALUE ary, VALUE num)
    {
        long r, n, i;

        n = RARRAY_LEN(ary);                  /* Array length */
        RETURN_SIZED_ENUMERATOR(ary, 1, &num, rb_ary_repeated_permutation_size);      /* Return Enumerator if no block */
        r = NUM2LONG(num);                    /* Permutation size from argument */

        if (r < 0) {
            /* no permutations: yield nothing */
        }
        else if (r == 0) { /* exactly one permutation: the zero-length array */
            rb_yield(rb_ary_new2(0));
        }
        else if (r == 1) { /* this is a special, easy case */
            for (i = 0; i < RARRAY_LEN(ary); i++) {
                rb_yield(rb_ary_new3(1, RARRAY_AREF(ary, i)));
            }
        }
        else {             /* this is the general case */
            volatile VALUE t0;
            long *p = ALLOCV_N(long, t0, r);
            VALUE ary0 = ary_make_shared_copy(ary); /* private defensive copy of ary */
            RBASIC_CLEAR_CLASS(ary0);

            rpermute0(n, r, p, ary0); /* compute and yield repeated permutations */
            ALLOCV_END(t0);
            RBASIC_SET_CLASS_RAW(ary0, rb_cArray);
        }
        return ary;
    }

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.

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`.

Examples:

- `size` is 1:

      p = []
      [0, 1, 2].repeated_permutation(1) {|permutation| p.push(permutation) }
      p # => [[0], [1], [2]]

- `size` is 2:

      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 `size` is zero, calls the block once with an empty array.

If `size` is negative, does not call the block:

    [0, 1, 2].repeated_permutation(-1) {|permutation| fail 'Cannot happen' }

With no block given, returns a new `Enumerator`.

Related: see Methods for Combining.

replace(other_array) → self

Replaces the elements of `self` with the elements of `other_array`, which must be an array-convertible object; returns `self`:

    a = ['a', 'b', 'c']   # => ["a", "b", "c"]
    a.replace(['d', 'e']) # => ["d", "e"]

Related: see Methods for Assigning.

Alias for: initialize_copy
reverse → new_array
Source

    static VALUE
    rb_ary_reverse_m(VALUE ary)
    {
        long len = RARRAY_LEN(ary);
        VALUE dup = rb_ary_new2(len);

        if (len > 0) {
            const VALUE *p1 = RARRAY_CONST_PTR(ary);
            VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1;
            do *p2-- = *p1++; while (--len > 0);
        }
        ARY_SET_LEN(dup, RARRAY_LEN(ary));
        return dup;
    }

Returns a new array containing the elements of `self` in reverse order:

    [0, 1, 2].reverse # => [2, 1, 0]

Related: see Methods for Combining.

reverse! → self
Source

    static VALUE
    rb_ary_reverse_bang(VALUE ary)
    {
        return rb_ary_reverse(ary);
    }

Reverses the order of the elements of `self`; returns `self`:

    a = [0, 1, 2]
    a.reverse! # => [2, 1, 0]
    a          # => [2, 1, 0]

Related: see Methods for Assigning.

reverse_each {|element| ... } → self
reverse_each → Enumerator
Source

    static VALUE
    rb_ary_reverse_each(VALUE ary)
    {
        long len;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        len = RARRAY_LEN(ary);
        while (len--) {
            long nlen;
            rb_yield(RARRAY_AREF(ary, len));
            nlen = RARRAY_LEN(ary);
            if (nlen < len) {
                len = nlen;
            }
        }
        return ary;
    }

When a block given, iterates backwards over the elements of `self`, passing, in reverse order, each element to the block; returns `self`:

    a = []
    [0, 1, 2].reverse_each {|element| a.push(element) }
    a # => [2, 1, 0]

Allows the array to be modified during iteration:

    a = ['a', 'b', 'c']
    a.reverse_each {|element| a.clear if element.start_with?('b') }
    a # => []

When no block given, returns a new `Enumerator`.

Related: see Methods for Iterating.

rindex(object) → integer or nil
rindex {|element| ... } → integer or nil
rindex → new_enumerator
Source

    static VALUE
    rb_ary_rindex(int argc, VALUE *argv, VALUE ary)
    {
        VALUE val;
        long i = RARRAY_LEN(ary), len;

        if (argc == 0) {
            RETURN_ENUMERATOR(ary, 0, 0);
            while (i--) {
                if (RTEST(rb_yield(RARRAY_AREF(ary, i))))
                    return LONG2NUM(i);
                if (i > (len = RARRAY_LEN(ary))) {
                    i = len;
                }
            }
            return Qnil;
        }
        rb_check_arity(argc, 0, 1);
        val = argv[0];
        if (rb_block_given_p())
            rb_warn("given block not used");
        while (i--) {
            VALUE e = RARRAY_AREF(ary, i);
            if (rb_equal(e, val)) {
                return LONG2NUM(i);
            }
            if (i > RARRAY_LEN(ary)) {
                break;
            }
        }
        return Qnil;
    }

Returns the index of the last element for which `object == element`.

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.

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`.

Related: see Methods for Querying.

rotate(count = 1) → new_array
Source

    static VALUE
    rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary)
    {
        VALUE rotated;
        const VALUE *ptr;
        long len;
        long cnt = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);

        len = RARRAY_LEN(ary);
        rotated = rb_ary_new2(len);
        if (len > 0) {
            cnt = rotate_count(cnt, len);
            ptr = RARRAY_CONST_PTR(ary);
            len -= cnt;
            ary_memcpy(rotated, 0, len, ptr + cnt);
            ary_memcpy(rotated, len, cnt, ptr);
        }
        ARY_SET_LEN(rotated, RARRAY_LEN(ary));
        return rotated;
    }

Returns a new array formed from `self` with elements rotated from one end to the other.

With non-negative numeric `count`, rotates elements from the beginning to the end:

    [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:

    [0, 1, 2, 3].rotate(22) # => [2, 3, 0, 1]

With a `count` of zero, rotates no elements:

    [0, 1, 2, 3].rotate(0) # => [0, 1, 2, 3]

With negative numeric `count`, rotates in the opposite direction, from the end to the beginning:

    [0, 1, 2, 3].rotate(-1) # => [3, 0, 1, 2]

If `count` is small (far from zero), uses `count % array.size` as the count:

    [0, 1, 2, 3].rotate(-21) # => [3, 0, 1, 2]

Related: see Methods for Fetching.

rotate!(count = 1) → self
Source

    static VALUE
    rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary)
    {
        long n = (rb_check_arity(argc, 0, 1) ? NUM2LONG(argv[0]) : 1);
        rb_ary_rotate(ary, n);
        return ary;
    }

Rotates `self` in place by moving elements from one end to the other; returns `self`.

With non-negative numeric `count`, rotates `count` elements from the beginning to the end:

    [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:

    [0, 1, 2, 3].rotate!(21) # => [1, 2, 3, 0]

If `count` is zero, rotates no elements:

    [0, 1, 2, 3].rotate!(0) # => [0, 1, 2, 3]

With a negative numeric `count`, rotates in the opposite direction, from end to beginning:

    [0, 1, 2, 3].rotate!(-1) # => [3, 0, 1, 2]

If `count` is small (far from zero), uses `count % array.size` as the count:

    [0, 1, 2, 3].rotate!(-21) # => [3, 0, 1, 2]

Related: see Methods for Assigning.

sample(random: Random) → object
sample(count, random: Random) → new_ary
Source

    # File array.rb, line 95
    def sample(n = (ary = false), random: Random)
      if Primitive.mandatory_only?
        # Primitive.cexpr! %{ rb_ary_sample(self, rb_cRandom, Qfalse, Qfalse) }
        Primitive.ary_sample0
      else
        # Primitive.cexpr! %{ rb_ary_sample(self, random, n, ary) }
        Primitive.ary_sample(random, n, ary)
      end
    end

Returns random elements from `self`, as selected by the object given by the keyword argument `random`.

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

Returns `nil` if `self` is empty:

    [].sample # => nil

With a non-negative numeric argument `count` given, returns a new array containing `count` random elements from `self`:

    a.sample(3) # => [8, 9, 2]
    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(50) # => [6, 4, 1, 8, 5, 9, 0, 2, 3, 7]

The object given with the keyword argument `random` is 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.

select {|element| ... } → new_array
select → new_enumerator
Source

    static VALUE
    rb_ary_select(VALUE ary)
    {
        VALUE result;
        long i;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        result = rb_ary_new2(RARRAY_LEN(ary));
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            if (RTEST(rb_yield(RARRAY_AREF(ary, i)))) {
                rb_ary_push(result, rb_ary_elt(ary, i));
            }
        }
        return result;
    }

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]
    a.select {|element| element.to_s.start_with?('b') }
    # => ["bar", :bam]

With no block given, returns a new `Enumerator`.

Related: see Methods for Fetching.

Also aliased as: filter, filter
select! {|element| ... } → self or nil
select! → new_enumerator
Source

    static VALUE
    rb_ary_select_bang(VALUE ary)
    {
        struct select_bang_arg args;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rb_ary_modify(ary);

        args.ary = ary;
        args.len[0] = args.len[1] = 0;
        return rb_ensure(select_bang_i, (VALUE)&args, select_bang_ensure, (VALUE)&args);
    }

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:

    a = [:foo, 'bar', 2, :bam]
    a.select! {|element| element.to_s.start_with?('b') } # => ["bar", :bam]

Returns `nil` if no elements were removed.

With no block given, returns a new `Enumerator`.

Related: see Methods for Deleting.

Also aliased as: filter!
shelljoin → string
Source

    # File lib/shellwords.rb, line 251
    def shelljoin
      Shellwords.join(self)
    end

Builds a command line string from an argument list `array` joining all elements escaped for the Bourne shell and separated by a space.

See `Shellwords.shelljoin` for details.

shift → object or nil
shift(count) → new_array or nil
Source

    static VALUE
    rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
    {
        VALUE result;
        long n;

        if (argc == 0) {
            return rb_ary_shift(ary);
        }

        rb_ary_modify_check(ary);
        result = ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST);
        n = RARRAY_LEN(result);
        rb_ary_behead(ary,n);

        return result;
    }

Removes and returns leading elements from `self`.

With no argument, removes and returns one element, if available, or `nil` otherwise:

    a = [0, 1, 2, 3]
    a.shift  # => 0
    a        # => [1, 2, 3]
    [].shift # => nil

With non-negative numeric argument `count` given, removes and returns the first `count` elements:

    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 `count` is large, removes and returns all elements:

    a = [0, 1, 2, 3]
    a.shift(50) # => [0, 1, 2, 3]
    a           # => []

If `self` is empty, returns a new empty array.

Related: see Methods for Deleting.

shuffle(random: Random) → new_array
Source

    # File array.rb, line 45
    def shuffle(random: Random)
      Primitive.rb_ary_shuffle(random)
    end

Returns a new array containing all elements from `self` in a random order, as selected by the object given by the 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 the keyword argument `random` is used as the random number generator.

Related: see Methods for Fetching.

shuffle!(random: Random) → self
Source

    # File array.rb, line 22
    def shuffle!(random: Random)
      Primitive.rb_ary_shuffle_bang(random)
    end

Shuffles all elements in `self` into a random order, as selected by the object given by the keyword argument `random`. Returns `self`:

    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 the keyword argument `random` is used as the random number generator.

Related: see Methods for Assigning.

size → integer

Returns the count of elements in `self`:

    [0, 1, 2].length # => 3
    [].length        # => 0

Related: see Methods for Querying.

Alias for: length
slice(index) → object or nil
slice(start, length) → object or nil
slice(range) → object or nil
slice(aseq) → object or nil

Returns elements from `self`; does not modify `self`.

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]
    a[0] # => :foo
    a[2] # => 2
    a # => [:foo, "bar", 2]

If `index` is negative, counts backwards from the end of `self`:

    a = [:foo, 'bar', 2]
    a[-1] # => 2
    a[-2] # => "bar"

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`:

    a = [:foo, 'bar', 2]
    a[0, 2] # => [:foo, "bar"]
    a[1, 2] # => ["bar", 2]

If `start + length` is greater than `self.length`, returns all elements from offset `start` to the end:

    a = [:foo, 'bar', 2]
    a[0, 4] # => [:foo, "bar", 2]
    a[1, 3] # => ["bar", 2]
    a[2, 2] # => [2]

If `start == self.size` and `length >= 0`, returns a new empty `Array`.

If `length` is negative, returns `nil`.

When a single `Range` argument `range` is given, treats `range.min` as `start` above and `range.size` as `length` above:

    a = [:foo, 'bar', 2]
    a[0..1] # => [:foo, "bar"]
    a[1..2] # => ["bar", 2]

Special case: If `range.start == a.size`, returns a new empty `Array`.

If `range.end` is negative, calculates the end index from the end:

    a = [:foo, 'bar', 2]
    a[0..-1] # => [:foo, "bar", 2]
    a[0..-2] # => [:foo, "bar"]
    a[0..-3] # => [:foo]

If `range.start` is negative, calculates the start index from the end:

    a = [:foo, 'bar', 2]
    a[-1..2] # => [2]
    a[-2..2] # => ["bar", 2]
    a[-3..2] # => [:foo, "bar", 2]

If `range.start` is larger than the array size, returns `nil`.

    a = [:foo, 'bar', 2]
    a[4..1] # => nil
    a[4..0] # => nil
    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.

    a = ['--', 'data1', '--', 'data2', '--', 'data3']
    a[(1..).step(2)] # => ["data1", "data2", "data3"]

Unlike slicing with range, if the start or the end of the arithmetic sequence is larger than array size, throws `RangeError`.

    a = ['--', 'data1', '--', 'data2', '--', 'data3']
    a[(1..11).step(2)]
    # RangeError (((1..11).step(2)) out of range)
    a[(7..).step(2)]
    # RangeError (((7..).step(2)) out of range)

If given a single argument, and its type is not one of the listed, tries to convert it to `Integer`, and raises if it is impossible:

    a = [:foo, 'bar', 2]
    # Raises TypeError (no implicit conversion of Symbol into Integer):
    a[:foo]

Related: see Methods for Fetching.

Alias for: []
slice!(index) → object or nil
slice!(start, length) → new_array or nil
slice!(range) → new_array or nil
Source

    static VALUE
    rb_ary_slice_bang(int argc, VALUE *argv, VALUE ary)
    {
        VALUE arg1;
        long pos, len;

        rb_ary_modify_check(ary);
        rb_check_arity(argc, 1, 2);
        arg1 = argv[0];

        if (argc == 2) {
            pos = NUM2LONG(argv[0]);
            len = NUM2LONG(argv[1]);
            return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
        }

        if (!FIXNUM_P(arg1)) {
            switch (rb_range_beg_len(arg1, &pos, &len, RARRAY_LEN(ary), 0)) {
              case Qtrue:
                /* valid range */
                return ary_slice_bang_by_rb_ary_splice(ary, pos, len);
              case Qnil:
                /* invalid range */
                return Qnil;
              default:
                /* not a range */
                break;
            }
        }

        return rb_ary_delete_at(ary, NUM2LONG(arg1));
    }

Removes and returns elements from `self`.

With numeric argument `index` given, removes and returns the element at offset `index`:

    a = ['a', 'b', 'c', 'd']
    a.slice!(2)   # => "c"
    a             # => ["a", "b", "d"]
    a.slice!(2.1) # => "d"
    a             # => ["a", "b"]

If `index` is negative, counts backwards from the end of `self`:

    a = ['a', 'b', 'c', 'd']
    a.slice!(-2) # => "c"
    a            # => ["a", "b", "d"]

If `index` is out of range, returns `nil`.

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 = ['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 = ['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 `length` is negative, returns `nil`.

With `Range` argument `range` given, treats `range.min` as `start` (as above) and `range.size` as `length` (as above):

    a = ['a', 'b', 'c', 'd']
    a.slice!(1..2) # => ["b", "c"]
    a              # => ["a", "d"]

If `range.start == a.size`, returns a new empty array:

    a = ['a', 'b', 'c', 'd']
    a.slice!(4..5) # => []

If `range.start` is larger than the array size, returns `nil`:

    a = ['a', 'b', 'c', 'd']
    a.slice!(5..6) # => nil

If `range.start` is negative, calculates the start index by counting backwards from the end of `self`:

    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.

sort → new_array
sort {|a, b| ... } → new_array
Source

    VALUE
    rb_ary_sort(VALUE ary)
    {
        ary = rb_ary_dup(ary);
        rb_ary_sort_bang(ary);
        return ary;
    }

Returns a new array containing the elements of `self`, sorted.

With no block given, compares elements using operator `<=>` (see `Object#<=>`):

    [0, 2, 3, 1].sort # => [0, 1, 2, 3]

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.

- Positive when `a` is to follow `b`.

Example:

    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.

Related: see Methods for Fetching.

sort! → self
sort! {|a, b| ... } → self
Source

    VALUE
    rb_ary_sort_bang(VALUE ary)
    {
        rb_ary_modify(ary);
        RUBY_ASSERT(!ARY_SHARED_P(ary));
        if (RARRAY_LEN(ary) > 1) {
            VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */
            struct ary_sort_data data;
            long len = RARRAY_LEN(ary);
            RBASIC_CLEAR_CLASS(tmp);
            data.ary = tmp;
            data.receiver = ary;
            RARRAY_PTR_USE(tmp, ptr, {
                ruby_qsort(ptr, len, sizeof(VALUE),
                           rb_block_given_p()?sort_1:sort_2, &data);
            }); /* WB: no new reference */
            rb_ary_modify(ary);
            if (ARY_EMBED_P(tmp)) {
                if (ARY_SHARED_P(ary)) { /* ary might be destructively operated in the given block */
                    rb_ary_unshare(ary);
                    FL_SET_EMBED(ary);
                }
                if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) {
                    ary_resize_capa(ary, ARY_EMBED_LEN(tmp));
                }
                ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp));
                ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp));
            }
            else {
                if (!ARY_EMBED_P(ary) && ARY_HEAP_PTR(ary) == ARY_HEAP_PTR(tmp)) {
                    FL_UNSET_SHARED(ary);
                    ARY_SET_CAPA(ary, RARRAY_LEN(tmp));
                }
                else {
                    RUBY_ASSERT(!ARY_SHARED_P(tmp));
                    if (ARY_EMBED_P(ary)) {
                        FL_UNSET_EMBED(ary);
                    }
                    else if (ARY_SHARED_P(ary)) {
                        /* ary might be destructively operated in the given block */
                        rb_ary_unshare(ary);
                    }
                    else {
                        ary_heap_free(ary);
                    }
                    ARY_SET_PTR(ary, ARY_HEAP_PTR(tmp));
                    ARY_SET_HEAP_LEN(ary, len);
                    ARY_SET_CAPA(ary, ARY_HEAP_LEN(tmp));
                }
                /* tmp was lost ownership for the ptr */
                FL_UNSET(tmp, FL_FREEZE);
                FL_SET_EMBED(tmp);
                ARY_SET_EMBED_LEN(tmp, 0);
                FL_SET(tmp, FL_FREEZE);
            }
            /* tmp will be GC'ed. */
            RBASIC_SET_CLASS_RAW(tmp, rb_cArray); /* rb_cArray must be marked */
        }
        ary_verify(ary);
        return ary;
    }

Like `Array#sort`, but returns `self` with its elements sorted in place.

Related: see Methods for Assigning.

sort_by! {|element| ... } → self
sort_by! → new_enumerator
Source

    static VALUE
    rb_ary_sort_by_bang(VALUE ary)
    {
        VALUE sorted;

        RETURN_SIZED_ENUMERATOR(ary, 0, 0, ary_enum_length);
        rb_ary_modify(ary);
        sorted = rb_block_call(ary, rb_intern("sort_by"), 0, 0, sort_by_i, 0);
        rb_ary_replace(ary, sorted);
        return ary;
    }

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:

    a = ['aaaa', 'bbb', 'cc', 'd']
    a.sort_by! {|element| element.size }
    a # => ["d", "cc", "bbb", "aaaa"]

For duplicate values returned by the block, the ordering is indeterminate, and may be unstable.

With no block given, returns a new `Enumerator`.

Related: see Methods for Assigning.

sum(init = 0) → object
sum(init = 0) {|element| ... } → object
Source

    static VALUE
    rb_ary_sum(int argc, VALUE *argv, VALUE ary)
    {
        VALUE e, v, r;
        long i, n;
        int block_given;

        v = (rb_check_arity(argc, 0, 1) ? argv[0] : LONG2FIX(0));

        block_given = rb_block_given_p();

        if (RARRAY_LEN(ary) == 0)
            return v;

        n = 0;
        r = Qundef;

        if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) {
            i = 0;
            goto init_is_a_value;
        }

        for (i = 0; i < RARRAY_LEN(ary); i++) {
            e = RARRAY_AREF(ary, i);
            if (block_given)
                e = rb_yield(e);
            if (FIXNUM_P(e)) {
                n += FIX2LONG(e); /* should not overflow long type */
                if (!FIXABLE(n)) {
                    v = rb_big_plus(LONG2NUM(n), v);
                    n = 0;
                }
            }
            else if (RB_BIGNUM_TYPE_P(e))
                v = rb_big_plus(e, v);
            else if (RB_TYPE_P(e, T_RATIONAL)) {
                if (UNDEF_P(r))
                    r = e;
                else
                    r = rb_rational_plus(r, e);
            }
            else
                goto not_exact;
        }
        v = finish_exact_sum(n, r, v, argc!=0);
        return v;

      not_exact:
        v = finish_exact_sum(n, r, v, i!=0);

        if (RB_FLOAT_TYPE_P(e)) {
            /*
             * Kahan-Babuska balancing compensated summation algorithm
             * See https://link.springer.com/article/10.1007/s00607-005-0139-x
             */
            double f, c;
            double x, t;

            f = NUM2DBL(v);
            c = 0.0;
            goto has_float_value;
            for (; i < RARRAY_LEN(ary); i++) {
                e = RARRAY_AREF(ary, i);
                if (block_given)
                    e = rb_yield(e);
                if (RB_FLOAT_TYPE_P(e))
                  has_float_value:
                    x = RFLOAT_VALUE(e);
                else if (FIXNUM_P(e))
                    x = FIX2LONG(e);
                else if (RB_BIGNUM_TYPE_P(e))
                    x = rb_big2dbl(e);
                else if (RB_TYPE_P(e, T_RATIONAL))
                    x = rb_num2dbl(e);
                else
                    goto not_float;

                if (isnan(f)) continue;
                if (isnan(x)) {
                    f = x;
                    continue;
                }
                if (isinf(x)) {
                    if (isinf(f) && signbit(x) != signbit(f))
                        f = NAN;
                    else
                        f = x;
                    continue;
                }
                if (isinf(f)) continue;

                t = f + x;
                if (fabs(f) >= fabs(x))
                    c += ((f - t) + x);
                else
                    c += ((x - t) + f);
                f = t;
            }
            f += c;
            return DBL2NUM(f);

          not_float:
            v = DBL2NUM(f);
        }

        goto has_some_value;
        init_is_a_value:
        for (; i < RARRAY_LEN(ary); i++) {
            e = RARRAY_AREF(ary, i);
            if (block_given)
                e = rb_yield(e);
          has_some_value:
            v = rb_funcall(v, idPLUS, 1, e);
        }
        return v;
    }

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, `[e0, e1, e2].sum` returns `init + e0 + e1 + e2`.

Examples:

    [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 `init` value and elements need not be numeric, but must all be `+`-compatible:

    # Raises TypeError: Array can't be coerced into Integer.
    [[:foo, :bar], ['foo', 'bar']].sum(2)

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:

    ['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#sum` method may not respect method redefinition of “+” methods such as `Integer#+`.

take(count) → new_array
Source

    static VALUE
    rb_ary_take(VALUE obj, VALUE n)
    {
        long len = NUM2LONG(n);
        if (len < 0) {
            rb_raise(rb_eArgError, "attempt to take negative size");
        }
        return rb_ary_subseq(obj, 0, len);
    }

Returns a new array containing the first `count` element of `self` (as available); `count` must be a non-negative numeric; does not modify `self`:

    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)   # => []

Related: see Methods for Fetching.

take_while {|element| ... } → new_array
take_while → new_enumerator
Source

    static VALUE
    rb_ary_take_while(VALUE ary)
    {
        long i;

        RETURN_ENUMERATOR(ary, 0, 0);
        for (i = 0; i < RARRAY_LEN(ary); i++) {
            if (!RTEST(rb_yield(RARRAY_AREF(ary, i)))) break;
        }
        return rb_ary_take(ary, LONG2FIX(i));
    }

With a block given, calls the block with each successive element of `self`; 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.take_while {|element| false }       # => []

With no block given, returns a new `Enumerator`.

Does not modify `self`.

Related: see Methods for Fetching.

to_a → self or new_array
Source

    static VALUE
    rb_ary_to_a(VALUE ary)
    {
        if (rb_obj_class(ary) != rb_cArray) {
            VALUE dup = rb_ary_new2(RARRAY_LEN(ary));
            rb_ary_replace(dup, ary);
            return dup;
        }
        return ary;
    }

When `self` is an instance of `Array`, returns `self`.

Otherwise, returns a new array containing the elements of `self`:

    class MyArray < Array; end
    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.

to_ary → self
Source

    static VALUE
    rb_ary_to_ary_m(VALUE ary)
    {
        return ary;
    }

Returns `self`.

to_h → new_hash
to_h {|element| ... } → new_hash
Source

    static VALUE
    rb_ary_to_h(VALUE ary)
    {
        long i;
        VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary));
        int block_given = rb_block_given_p();

        for (i=0; i<RARRAY_LEN(ary); i++) {
            const VALUE e = rb_ary_elt(ary, i);
            const VALUE elt = block_given ? rb_yield_force_blockarg(e) : e;
            const VALUE key_value_pair = rb_check_array_type(elt);
            if (NIL_P(key_value_pair)) {
                rb_raise(rb_eTypeError, "wrong element type %"PRIsVALUE" at %ld (expected array)",
                         rb_obj_class(elt), i);
            }
            if (RARRAY_LEN(key_value_pair) != 2) {
                rb_raise(rb_eArgError, "wrong array length at %ld (expected 2, was %ld)",
                    i, RARRAY_LEN(key_value_pair));
            }
            rb_hash_aset(hash, RARRAY_AREF(key_value_pair, 0), RARRAY_AREF(key_value_pair, 1));
        }
        return hash;
    }

Returns a new hash formed from `self`.

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', 'zero'], ['bar', 'one'], ['baz', 'two']]
    a.to_h # => {"foo"=>"zero", "bar"=>"one", "baz"=>"two"}
    [].to_h # => {}

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:

    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.

to_s → new_string

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.

Alias for: inspect
transpose → new_array
Source

    static VALUE
    rb_ary_transpose(VALUE ary)
    {
        long elen = -1, alen, i, j;
        VALUE tmp, result = 0;

        alen = RARRAY_LEN(ary);
        if (alen == 0) return rb_ary_dup(ary);
        for (i=0; i<alen; i++) {
            tmp = to_ary(rb_ary_elt(ary, i));
            if (elen < 0) {         /* first element */
                elen = RARRAY_LEN(tmp);
                result = rb_ary_new2(elen);
                for (j=0; j<elen; j++) {
                    rb_ary_store(result, j, rb_ary_new2(alen));
                }
            }
            else if (elen != RARRAY_LEN(tmp)) {
                rb_raise(rb_eIndexError, "element size differs (%ld should be %ld)",
                         RARRAY_LEN(tmp), elen);
            }
            for (j=0; j<elen; j++) {
                rb_ary_store(rb_ary_elt(result, j), i, rb_ary_elt(tmp, j));
            }
        }
        return result;
    }

Returns a new array that is `self` as a transposed matrix:

    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.

union(*other_arrays) → new_array
Source

    static VALUE
    rb_ary_union_multi(int argc, VALUE *argv, VALUE ary)
    {
        int i;
        long sum;
        VALUE hash;

        sum = RARRAY_LEN(ary);
        for (i = 0; i < argc; i++) {
            argv[i] = to_ary(argv[i]);
            sum += RARRAY_LEN(argv[i]);
        }

        if (sum <= SMALL_ARRAY_LEN) {
            VALUE ary_union = rb_ary_new();

            rb_ary_union(ary_union, ary);
            for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]);

            return ary_union;
        }

        hash = ary_make_hash(ary);
        for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]);

        return rb_hash_values(hash);
    }

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]

Preserves order (preserving the position of the first found):

    [3, 2, 1, 0].union([5, 3], [4, 2]) # => [3, 2, 1, 0, 5, 4]

With no arguments given, returns a copy of `self`.

Related: see Methods for Combining.

uniq → new_array
uniq {|element| ... } → new_array
Source

    static VALUE
    rb_ary_uniq(VALUE ary)
    {
        VALUE hash, uniq;

        if (RARRAY_LEN(ary) <= 1) {
            hash = 0;
            uniq = rb_ary_dup(ary);
        }
        else if (rb_block_given_p()) {
            hash = ary_make_hash_by(ary);
            uniq = rb_hash_values(hash);
        }
        else {
            hash = ary_make_hash(ary);
            uniq = rb_hash_values(hash);
        }

        return uniq;
    }

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 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 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.

uniq! → self or nil
uniq! {|element| ... } → self or nil
Source

    static VALUE
    rb_ary_uniq_bang(VALUE ary)
    {
        VALUE hash;
        long hash_size;

        rb_ary_modify_check(ary);
        if (RARRAY_LEN(ary) <= 1)
            return Qnil;
        if (rb_block_given_p())
            hash = ary_make_hash_by(ary);
        else
            hash = ary_make_hash(ary);

        hash_size = RHASH_SIZE(hash);
        if (RARRAY_LEN(ary) == hash_size) {
            return Qnil;
        }
        rb_ary_modify_check(ary);
        ARY_SET_LEN(ary, 0);
        if (ARY_SHARED_P(ary)) {
            rb_ary_unshare(ary);
            FL_SET_EMBED(ary);
        }
        ary_resize_capa(ary, hash_size);
        rb_hash_foreach(hash, push_value, ary);

        return ary;
    }

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 elements:

    a = [0, 0, 1, 1, 2, 2]
    a.uniq! # => [0, 1, 2]
    a.uniq! # => nil

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 } # => nil

Related: see Methods for Deleting.

unshift(*objects) → self
Source

    VALUE
    rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary)
    {
        long len = RARRAY_LEN(ary);
        VALUE target_ary;

        if (argc == 0) {
            rb_ary_modify_check(ary);
            return ary;
        }

        target_ary = ary_ensure_room_for_unshift(ary, argc);
        ary_memcpy0(ary, 0, argc, argv, target_ary);
        ARY_SET_LEN(ary, len + argc);
        return ary;
    }

Prepends the given `objects` to `self`:

    a = [:foo, 'bar', 2]
    a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2]

Related: `Array#shift`; see also Methods for Assigning.

Also aliased as: prepend
values_at(*specifiers) → new_array
Source

    static VALUE
    rb_ary_values_at(int argc, VALUE *argv, VALUE ary)
    {
        long i, olen = RARRAY_LEN(ary);
        VALUE result = rb_ary_new_capa(argc);
        for (i = 0; i < argc; ++i) {
            append_values_at_single(result, ary, olen, argv[i]);
        }
        RB_GC_GUARD(ary);
        return result;
    }

Returns elements from `self` in a new array; does not modify `self`.

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`.

In brief:

    a = ['a', 'b', 'c', 'd']

    # 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.

    # 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.values_at(-3..3)  # => ["b", "c", "d"]     # Negative range.begin counts backwards.
    a.values_at(-50..3)                          # Raises RangeError.

    a.values_at(1..-2)  # => ["b", "c"]          # Negative range.end counts backwards.
    a.values_at(1..-50) # => []                  # No such elements.

    # Mixture of specifiers.
    a.values_at(2..3, 3, 0..1, 0) # => ["c", "d", "d", "a", "b", "a"]

With no `specifiers` given, returns a new empty array:

    a = ['a', 'b', 'c', 'd']
    a.values_at # => []

For each numeric specifier `index`, includes an element:

- For each non-negative numeric specifier `index` that is in-range (less than `self.size`), includes the element at offset `index`:

      a.values_at(0, 2)     # => ["a", "c"]
      a.values_at(0.1, 2.9) # => ["a", "c"]

- 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.

zip(*other_arrays) → new_array
zip(*other_arrays) {|sub_array| ... } → nil
Source

    static VALUE
    rb_ary_zip(int argc, VALUE *argv, VALUE ary)
    {
        int i, j;
        long len = RARRAY_LEN(ary);
        VALUE result = Qnil;

        for (i=0; i<argc; i++) {
            argv[i] = take_items(argv[i], len);
        }

        if (rb_block_given_p()) {
            int arity = rb_block_arity();

            if (arity > 1) {
                VALUE work, *tmp;

                tmp = ALLOCV_N(VALUE, work, argc+1);

                for (i=0; i<RARRAY_LEN(ary); i++) {
                    tmp[0] = RARRAY_AREF(ary, i);
                    for (j=0; j<argc; j++) {
                        tmp[j+1] = rb_ary_elt(argv[j], i);
                    }
                    rb_yield_values2(argc+1, tmp);
                }

                if (work) ALLOCV_END(work);
            }
            else {
                for (i=0; i<RARRAY_LEN(ary); i++) {
                    VALUE tmp = rb_ary_new2(argc+1);

                    rb_ary_push(tmp, RARRAY_AREF(ary, i));
                    for (j=0; j<argc; j++) {
                        rb_ary_push(tmp, rb_ary_elt(argv[j], i));
                    }
                    rb_yield(tmp);
                }
            }
        }
        else {
            result = rb_ary_new_capa(len);

            for (i=0; i<len; i++) {
                VALUE tmp = rb_ary_new_capa(argc+1);

                rb_ary_push(tmp, RARRAY_AREF(ary, i));
                for (j=0; j<argc; j++) {
                    rb_ary_push(tmp, rb_ary_elt(argv[j], i));
                }
                rb_ary_push(result, tmp);
            }
        }

        return result;
    }

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.

Example:

    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.

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)
    pp d
    # =>
    [[:a0, :b0, :c0],
     [:a1, :b1, :c1],
     [:a2, :b2, :c2],
     [:a3, :b3, :c3]]

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)
    pp d
    # =>
    [[:a0, :b0, :c0],
     [:a1, :b1, :c1],
     [:a2, :b2, nil],
     [:a3, nil, nil]]

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)
    pp d
    # =>
    [[:a0, :b0, :c0],
     [:a1, :b1, :c1],
     [:a2, :b2, :c2],
     [:a3, :b3, :c3]]

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| d.push(sub_array.reverse) } # => nil
    pp d
    # =>
    [[:c0, :b0, :a0],
     [:c1, :b1, :a1],
     [:c2, :b2, :a2],
     [:c3, :b3, :a3]]

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.

Related: see Methods for Converting.