Array#push

Updated March 31, 2026 · Array Methods
ruby array push append stdlib

Array#push

Appends one or more elements to the end of an array. The array is modified in place, and the method returns the same array object.

Basic Usage

fruits = ["apple", "banana"]
fruits.push("cherry")
# => ["apple", "banana", "cherry"]

fruits
# => ["apple", "banana", "cherry"]

push mutates the original array — no new array is created. The return value is the same object that was modified.

Appending Multiple Elements

Unlike the << operator, push accepts multiple arguments:

queue = [1, 2]
queue.push(3, 4, 5)
# => [1, 2, 3, 4, 5]

Each argument is appended in order, as if you called push repeatedly:

letters = []
letters.push("a")
letters.push("b", "c")
# => ["a", "b", "c"]

push vs <<

The << operator appends exactly one element. It does not accept multiple arguments:

nums = [1, 2]
nums << 3
# => [1, 2, 3]

nums << 4 << 5
# => [1, 2, 3, 4, 5]

# This would NOT work as expected:
nums << 6 << 7
# => [1, 2, 3, 4, 5, 6, 7]

push is cleaner when appending multiple unrelated elements or when the number of elements is dynamic:

items = []
new_items = ["a", "b", "c"]
items.push(*new_items)  # splat expands the array
# => ["a", "b", "c"]

push vs concat

concat takes a single array argument and appends all of its elements:

a = [1, 2]
a.concat([3, 4])
# => [1, 2, 3, 4]

push with multiple arguments achieves the same result, but treats each argument as a separate element to append:

a = [1, 2]
a.push(*[3, 4])
# => [1, 2, 3, 4]

The key difference: concat expects an array, push expects individual elements (or an array with splat).

append — An Alias

append is an alias for push. They are functionally identical:

a = [1, 2]
a.append(3)
# => [1, 2, 3]

a.push(4)
# => [1, 2, 3, 4]

Use whichever reads more naturally in your context. push is more common; append may read better when the intent is clearly to add to a collection.

Practical Examples

Building a List

selected = []
loop do
  item = gets.chomp
  break if item.empty?
  selected.push(item)
end

Queue Simulation

queue = []
queue.push("task1")
queue.push("task2")

current = queue.shift
# => "task1"
queue
# => ["task2"]

push adds to the back, shift removes from the front — a classic FIFO queue.

Collecting Results

results = []
[1, 2, 3, 4, 5].each do |n|
  results.push(n * 2) if n.even?
end
results
# => [4, 8]

Flattening While Building

layers = [[1, 2], [3, 4], [5, 6]]
flat = []
layers.each { |layer| flat.push(*layer) }
flat
# => [1, 2, 3, 4, 5, 6]

Using push(*array) unpacks an array so its elements are appended individually.

Return Value

push always returns the same array object that was modified:

original = ["a", "b"]
returned = original.push("c")
returned.object_id == original.object_id
# => true

This allows chaining, though it is uncommon:

[].push("a").push("b")
# => ["a", "b"]

Performance Notes

Appending to the end of a Ruby array is amortized O(1). Ruby arrays maintain a buffer of extra capacity, so most push calls do not require reallocation. When the buffer is exhausted, Ruby doubles the array’s capacity and copies the elements — an O(n) operation that happens rarely.

Because of this, repeatedly pushing to an array is efficient. Building an array by repeatedly calling push is faster than creating a new array with [x, y, z, ...] syntax if the number of elements is not known at write time.

See Also