Array#push
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
- /reference/array-methods/array-map/ — transform each element in an array
- /reference/array-methods/array-select/ — filter array elements
- /reference/enumerable/enumerable-reduce/ — reduce an array to a single value