I honestly considered skipping the first method mentioned in the Array docs because I’ve already done a post that covers them when I was going through the summary section. Instead, I decided I would try to see if there were any differences between using [] and #new before skipping. It turns out there is.
[]
There are three different ways to use this one method…simply by itself.
Following a call to the Array object
Array["I", "remember", "I", "put", "on", "my", "socks"] => ["I", "remember", "I", "put", "on", "my", "socks"]
Following a period which itself follows a call to the Array object
Array.[]("I", "remember", "I", "put", "on", "my", "socks") => ["I", "remember", "I", "put", "on", "my", "socks"]
Simply by itself
["I", "remember", "I", "put", "on", "my", "socks"] => ["I", "remember", "I", "put", "on", "my", "socks"]
The only flexibility lies in how to use it. Give it what you want to be in the Array and you’re done.
#new
This one takes more than just the objects you want in your array, it can also accept the size or a block. Size will default to 0 and the objects within the array will default to nil.
Size and objects
Array.new => [] Array.new(5) => [nil, nil, nil, nil, nil] Array.new("I remember I put on my shoes") TypeError: no implicit conversion of String into Integer
For the first, the default size is 0 since I gave nothing and so we get an empty array in return. When, I give the size, I at least get a bunch of nil objects. Note that the last statement returns an error because the first argument should be a number (the size).
Now, let’s give both arguments…
Array.new(3, "I remember I put on my shoes") => ["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"]
We can also copy another array by referencing the one we wish to copy in the default argument position…
i_remember = Array.new(3, "I remember I put on my shoes") => ["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"] something_missing = Array.new(2, i_remember) => [["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"], ["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"]]
Now we have an array of two arrays. We took the i_remember array as our default object and put it in our new something_missing array to get to the size we requested (2). Note that these are separate objects, so if we called decided to copy within a size argument and create effectively the same array they would still not return true for a #equal? call…
i_remember = Array.new(3, "I remember I put on my shoes") => ["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"] something_missing = Array.new(i_remember) => ["I remember I put on my shoes", "I remember I put on my shoes", "I remember I put on my shoes"] i_remember.equal?(something_missing) => false
Using a block
When we use a block, we simply give the size argument first, then go ahead with our block. The block will be given the current index being created.
Array.new{|current_index| "I remember I put on #{(current_index * 2)} ties"} => [] Array.new(3){|current_index| "I remember I put on #{(current_index * 2)} ties"} => ["I remember I put on 0 ties", "I remember I put on 2 ties", "I remember I put on 4 ties"]
Without a size argument, we get an empty array. In the second example, I simply multiply the current index by 2 within string interpolation to output something that has a bit more variety that our previous arrays.
About that reference to the same object…
If you go the first route and simply copy a Hash, any changes you make to one object in that array will affect all of them.
something_missing = Array.new(2, Hash.new) => [{}, {}] something_missing[0]['tie'] = 'purple' => "purple" something_missing => [{"tie"=>"purple"}, {"tie"=>"purple"}]
This problem does not happen with a String, whether you use #new or simply give a literal string like I’ve done in many of the examples above.
something_missing = Array.new(2, "I remember I put on my tie") => ["I remember I put on my tie", "I remember I put on my tie"] something_missing[1] = "That was printed" => "That was printed" something_missing => ["I remember I put on my tie", "That was printed"]
You can also avoid this by using the block instead to copy a Hash since now the objects are all unique.
something_missing = Array.new(2){Hash.new()} => [{}, {}] something_missing[0]['tie'] = 'purple' => "purple" something_missing => [{"tie"=>"purple"}, {}]
Today’s lorem ipsum is brought to us by the late Shel Silverstein and his poem, “SOMETHING MISSING”
I remember I put on my socks,
I remember I put on my shoes.
I remember I put on my tie
That was printed
In beautiful purples and blues.
I remember I put on my coat,
To look perfectly grand at the dance,
Yet I feel there is something
I may have forgot—
What is it? What is it?…