[] vs .new with Arrays

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?…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s