Weird Things I Encountered In My Development Journey Explained

Using Shovel Operator in Ruby Arrays

Shan Shaji
2 min readMar 18, 2021

I am a Full Stack Dev, who mostly works with Ruby and JS. In my career, I have encountered lots of wtf moments. I am here to discuss some of them.

So I was casually explaining arrays to my friend, how to create them, read them and modify them. I started explaining by creating an array of 5 elements with a fruit name and storing it into variable a.

a = Array.new(5, "Apple")
a
["Apple", "Apple", "Apple", "Apple", "Apple"]

I showed him the output by printing a. Then I asked him to change the value of index 2 to “Orange”, which he did quickly and then we printed the output:

a[2]="Orange"
a
["Apple", "Apple", "Orange", "Apple", "Apple"]

Until here everything was working the way we intended. Then I asked him to modify index 1 from “Apple” to “Apple Sauce”, which he did quickly too. But the output surprised us.

a[1] << " Sauce"
a
["Apple Sauce", "Apple Sauce", "Orange", "Apple Sauce", "Apple Sauce"]

Instead of changing one element in index 1, it changed all of them. The very first thing that this strikes me to do was check the object id of the elements, for which I used the object_id method.

a[0].object_id
200
a[1].object_id
200
a[2].object_id
220 #this is because we changed value to orange using an assignment(=) operator.
a[3].object_id
200
a[4].object_id
200

This explained a lot to us. When we were creating the array using Array.new(5,"Apple") “Apple” was created once in the memory and we created an array with 5 elements pointing to the same “Apple”. When we changed the value of index 2 to “Orange”, we re-assigned the value (hence creating a new object_id).

But when we used the shovel operator(<<), instead of creating a new string, we worked on the original string. a[1]<< “ Sauce” appended the string “ Sauce” to the original string, causing it to change in all the places it was referring to.

The function clear is another example to illustrate the same. clear makes a string empty. so when we do a[3].clear , the String “Apple Sauce” which is created once in memory, will change into an empty string (“”). Resulting in an array that looks like the one below

["", "", "Orange", "", ""]

Basically, we created the array and assigned the string “Apple” to the elements in the array. This meant that each element was pointing to the same string “Apple”. When appending/clearing an element in the array, the changes are applied to ALL elements because they are pointing to the same string.

--

--

Shan Shaji

End to End Product Developer with an immense passion for Rails and React. https://github.com/shanshaji