A new array can be created by using two different ways in ruby and can contain different types of objects.

Using literal constructor.

foo = [] #=> []

And, by explicitly calling ::new

foo = Array.new #=> []

Array.new provides us with some control to pass options(arguments).

Array.new(size, default): size the initial size of the Array and default a default object.

Array.new(4)       #=> [nil, nil, nil, nil]
Array.new(4, false) #=> [false, false, false, false]

The default argument populates the array with a default value. It is recommended to use only symbols, numbers or boolean to instantiate arrays i.e immutable objects.

Now, if you try to pass Hash.new as the default argument and then assign the value to any of the hash element, the same object will be used as the value for all the array elements.

ary = Array.new(3, Hash.new)  # => [{}, {}, {}]
ary[1][:b] = 2                # => 2

ary                           # => [{:b=>2}, {:b=>2}, {:b=>2}]

If we check the object_id, the object ids are same for all the elements.

ary[1].object_id  #=> 70303253290780
ary[2].object_id  #=> 70303253290780

To create a array with seperate objects you can pass a block.

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

ary2[0][:a] = 1 #=> 1
ary2[1][:b] = 2 #=> 2

ary2 #=> [{:a=>1}, {:b=>2}, {}]

Now, if we check the object ids agian, they are different for each element.

ary2[0].object_id #=> 70303253381860
ary2[1].object_id #=> 70303253381780

Using this method you can pass mutable objects such as hashes, strings or arrays.