What is the difference between << and +=?

arrays, ruby

Solution

They exhibit fairly different behaviors. One creates and assigns a new `Array` object, the other modifies an existing object.

`+=` would be the same as `second_array = second_array + third_array`. This sends the `+` message to the `second_array` object passing `third_array` as the argument.

Per the documentation `Array.+` returns a new array object built by concatenating the two arrays. This will return a new object.

`Array.<<` simply push the parameter to the end of the existing array object:

second_array = []
second_array.object_id = 1234

second_array += [1,2,3,4]
second_array.object_id = 5678

second_array << 5
second_array.object_id = 5678

There is also a difference in how the parameter is added. By adding other elements, it will help see why your arrays are not equal:

second_array = [1, 2, 3]

# This will push the entire object, in this case an array
second_array << [1,2]
# => [1, 2, 3, [1,2]]

# Specifically appends the individual elements,
# not the entire array object
second_array + [4, 5]
# => [1, 2, 3, [1,2], 4, 5]

This is because `Array.+` uses concatenation instead of pushing. Unlike `Array.concat` which modifies the existing object, `Array.+` returns a new object.

You can think of a Ruby implementation like:

class Array
  def +(other_arr)
    dup.concat(other_arr)
  end
end

In your specific example, your objects look like this at the end:

first_array  = [[[1, 2, 3, 4, 5, 6, 7, 8, 9]]] # [] << [] << (1..9).to_a
second_array =  [[1, 2, 3, 4, 5, 6, 7, 8, 9]]  # [] + ([] << (1..9).to_a)
third_array  =  [[1, 2, 3, 4, 5, 6, 7, 8, 9]]  # [] << (1..9).to_a

Problem

I have been playing around with arrays a bit, and found myself in trouble understanding the following code: ``` first_array = [] second_array = [] third_array = [] # I initialized 3 empty arrays third_array << [1,2,3,4,5,6,7,8,9] # I loaded 1..9 into third_array[0] puts third_array.size # => 1 first_array << third_array # 1..9 was loaded into first_array[0] second_array += third_array # 1..9 was loaded into second_array[0] puts first_array == third_array # false puts second_array == third_array # true puts first_array == second_array # false puts first_array.size # 1 puts second_array.size # 1 puts third_array.size # 1 ``` What happened with this? ``` second_array += third_array # I have no clue ``` Why aren't all the arrays equal to each other?

Original source