The Basics of Variable Assignment in Ruby

Tim Freeman
Hackmamba
Published in
6 min readAug 2, 2017

Variables are one of the cornerstones of programming, and, like anything, understanding them is key to being able to use them effectively.

Why Variables?

Programmers assign pieces of data to variables for many reasons, but I will list a few of the main ones so that you have a very general understanding:

  • Variables are often easier to remember and type than the actual information we are working with (e.g. — patient_address vs ‘1234 Amityville Lane, Apt 3., Anytown, New York, 67890’).
  • Programmers often want to start with a piece of data in one state but end with it in a maybe-quite-complicated different state, and assigning data to variables makes that process much easier to manage and follow.
  • Assigning data to variables gives code longterm manageability. Programmers come and programmers go, but programs exist until they are deleted. With the right variable names, any programmer can look at your code — even after you’ve left for another opportunity — and know what is going on, which is key to managing code longterm.

Basic Variable Assignment

A quick exploration of Ruby variables and their behaviors reveals a lot, and hopefully you are here to do just that, explore. Feel free to open up interactive ruby (irb) in your terminal and code along to test this stuff out. Let’s start with the most basic of basics, the assigning of variables to barewords:

a = "Ruby"

In the above code, we have assigned a value of “Ruby” to the bareword a, which tells our program that from now on when we use a we are really talking about the string “Ruby”. This is clearly shown by just typing the letter a again and hitting enter:

a
=> "Ruby"

But, this still leaves some questions as to the actual relationship between our a variable and it’s value. Let’s gather a bit more information by asking our variable for it’s object_id:

a
=> "Ruby"
a.object_id
=> 70211214754080

Every bit of data that is created during the running of software is stored in memory, and all of those bits of data are associated with storage reference points so that the computer can find them again if need be. Since (almost) everything is an object in Ruby*, we can run the standard #object_id method on the variable to see its memory address. In this case, the return value for a.object_id is 70211214754080 (If you’re coding along, your memory address will be different than this one. Don’t be alarmed.) Let’s try assigning the string “Ruby” to another variable and see what happens to learn more:

*(If you don’t know what I mean here, you can pause now to read this or any other tutorial of Ruby objects on the web. You don’t necessarily need to fully understand Ruby’s object model to get a general understanding of variables to start, but knowledge of it will certainly enhance your ability to really internalize Ruby’s take on variables.)

a = "Ruby"a
=> "Ruby"
a.object_id
=> 70211214754080
b = "Ruby"b.object_id
=> 70211223067580

Hm. As you can see, the memory addresses of a and b are different even though they both appear to equal the same thing, and if you are like I was when I first started out, you are probably wondering why. This is because of the way(s) in which Ruby utilizes variable assignments AND the way(s) in which Ruby deals with strings (and other objects, for that matter). When we initially assign the string “Ruby” to the bareword a, the computer creates a new string object of “Ruby” since that string can’t exist in memory until we type it in. The letters, numbers, and/or symbols of the string are (mostly) irrelevant to the computer — and to us for the moment. The only thing that matters at this point is that our actions create a string and that said string is now stored in the 70211214754080 location in memory. By assigning that new string to the variable a, we are simply telling the computer that we want to use a as a reference point for the string object that we just created — so that we don’t have to remember 70211214754080. From this point on in our program, if we type a, Ruby will know that what we really mean is the piece of data that is located at 70211214754080 in memory which also happens to have the value of “Ruby” as per our assignment, though, the computer doesn’t actually care about that.

This helps explain why b’s location in memory is different than a’s. b is also a reference point to a memory location of a new string that we have created, regardless of it’s value. The fact that b’s string object also says “Ruby” is of no significance to the computer while the object is stored away. It just takes what we create and stores it for potential later use and agrees to let us call it b until further notice. a’s string object and b’s string object contain the same values, but they are different string objects that live at different temporary addresses in our computer.

Slightly More Advanced —Variables Are Pass-By-Value In Ruby

First, let’s look at a bit more code:

a = "Ruby"b = aa
=> "Ruby"
b
=> "Ruby
a.object_id
=> 70211214754080
b.object_id
=> 70211214754080

We assigned “Ruby” to a, assigned to b to a, and can now see that a and b are both pointing to the same object in memory by calling #object_id. Simple. But, there is still more to know…

Ruby is a pass-by-value language (as opposed to a pass-by-reference language). When we assign b to a, we are simply telling b to reference whatever it is that a is referencing, in this case, our string object “Ruby”. The computer connects b directly to that string object. It does not connect b to the object through a. This means that if we reassign a and give the computer a new object for it to reference, b will still refer to the old string object. See below:

a = "Ruby"b = aa
=> "Ruby"
b
=> "Ruby"
a.object_id
=> 70211214754080
b.object_id
=> 70211214754080
a = "I have changed"b
=> "Ruby"

This same scenario, however, would play out differently if we simply modified our string object instead of creating a new one and telling a to reference that one instead. Look:

a = "Ruby"b = aa
=> "Ruby"
b
=> "Ruby"
a << " is great"
=> "Ruby is great"
b
=> "Ruby is great"

Since we simply mutated our original string object but did not create a new one and assign a to it, a and b are both still referencing the same original string object and, thus, still hold the same value.

Another — and perhaps easier — example can be seen with an array. I’ll comment explanations of what is going on:

#assign a to an array value with 3 elements
a = [1,2,3]
#get a's object_id for reference
a.object_id
=> 70211214067539
#assign b to whatever memory location a is currently referencing
b = a
#confirm that b has the same object_id as a
b.object_id
=> 70211214067539
#add a new element to the a array
a << 4
=> [1,2,3,4]
#see that a is still pointing to the same memory location
a.object_id
=> 70211214067539
#confirm that b now has that new element, too
b
=> [1,2,3,4]
#assign a to a new array
a = [5,6,7,8]
#see that a's memory location reference has changed (because we created a new piece of data for it to reference)
a.object_id
=> 70211214001628
#see that b is still referencing the original object
b
=> [1,2,3,4]

Important Takeaways

Hopefully, at this point you have a general understanding of variable assignment in Ruby. There are definitely more advanced topics to be discussed concerning variables, but for the early stages, there’s just a few key things to remember:

  • Variables in Ruby are references to locations in memory, not references to values themselves
  • Variables in Ruby are pass-by-value, not pass-by-reference (Some people say that Ruby is a pass-by-reference-value language, but that’s a conversation for another day.)
  • Mutating an existing piece of data will return the newer version of that data to any variable(s) pointing to it’s memory location
  • Creating a new piece of data and assigning an existing variable to it will change the memory location reference (and thus the value) of that variable but will not affect any other variable(s) that happen to point to the memory location of the original piece of data

If you walk away from this post knowing these few things, you’ll have a lot more to learn, but you’ll definitely be on the right track.

“The most important property of a program is whether it accomplishes the intention of its user.” — C.A.R. Hoare

--

--