Advice for Ruby Programming Foundations Written Assessment(Part 4)

Srdjan Coric
Srdjan Coric
Published in
4 min readSep 24, 2017

Mutating/Non-mutating Ruby methods

So what are mutating methods in Ruby? Shortest answer would be, that those are methods which are changing the value of a calling object. It’s best to explain it with example though…

So what is happening here?

On line 1 we are initializing local variable a and assigning to it string object with value hello .

On line 3 we are outputting value of this string object and returning nil.

On line 4 we are calling method object_id on local variable a to check what is the id of the object this variable is referencing. This number will be different for you, but it doesn’t matter. We will get to the point of this on line 9. Until then…

On line 6 we are calling method String#upcase! on the object variable a is pointing to(pointing to is synonym of references). This method is mutating method which means it is changing value of the object that is calling it, so the object stays the same.

As we can see, on line 8 puts method is outputting string HELLO and what is most important to us on line 9 we can see that the object hasn’t changed see it still has the same object_id.

Usually mutating methods end with bang ! but you can encounter methods which are mutating and not include ! so check Ruby docs to see if the method is mutating or not.

In Ruby docs if it says upcase! -> str that means it is mutating since it is returning the same string. If it is not mutating instead of str there would be new_str like it is for upcase i.e. upcase -> new_str .

And while we are talking about upcase we can explain non-mutating methods we the example similar to the one above.

Lines 1-4 are the same. Then on line 5 we are calling method String#upcase on object which local variable a is referencing and you would expect that line 8 will output string HELLO but no, it outputs hello. What happened here?

Well, on line 6 upcase method call actually returns new string object and doesn’t change the value of our calling object. If we called method puts and passed in as argument upcase method call on variable a like this puts a.upcase that would output HELLO but our variable a would remain intact.

Also, we could have assigned return value of upcase method call to another local variable b for example ( b = a.upcase ) and in that case local variable b would would point to a string object with value HELLO and it would have different object_id also.

Since I have been talking about object_ids I will explain this a bit more with one example :

Try answering these three questions above without looking answers…

To the first question, the answer is actually no. On lines 1-3 we are initializing 3 local variables a, b and c which all have the same value name but they are not pointing to the same object. Local variable a is pointing to one string object with value name , local variable b is pointing to some other string object with the same value name and same goes for local variable c . And that complements my explanation in the last part where I have said that objects are just physical space in memory. And these three objects occupy different physical space in memory, and just have the same value.

What is happening on lines 13-14 ? On line 13 , we are reassigning local variable a to point to the same object as local variable c is pointing to. So now, local variable a and c are pointing to one object (the one that only local variable c was pointing to) and local variable b is pointing to another one. Then, on line 14 we are reassigning local variable b to point to the same object local variable a is pointing too which is actually the same object that local variable c is pointing to, so now all three local variables point to the same object.

Finally on lines 21-23 we are reassigning again local variables a , b and c so they should all point to different objects again? Well, not really. Integers and symbols in Ruby with same values occupy the same physical space in memory(they are the same objects) so integer 4 will always be the same object with same object_id even though you assign it to different local variables. Same goes with symbols :

Local variables a , b and c are pointing to the same object with the same object_id.

Let me explain now what Ruby’s += operator first.

This operator can be confusing since it feels like it should be mutating object. Consider this code :

On line 5 haven’t we just mutated object that local variables a was pointing to by concatenating another string object to it? Not really… += operator and -= , *= etc. are the same is just reassignment operator and line 5 can be written like this a = a + 'world' . So we are actually reassigning local variable a to a different object with a value hello world , so the outputs on lines 3 and 7 won’t be the same.

That’s it guys. I hope that it was useful for you and that it will help you pass the written part of the Ruby Programming Foundations Assessment.

--

--