Back-end Engineering Articles

I write and talk about backend stuff like Ruby, Ruby On Rails, Databases, Testing, Architecture / Infrastructure / System Design, Cloud, DevOps, Backgroud Jobs, some JS stuff and more...

Github:
/danielmoralesp
Twitter:
@danielmpbp

2024-09-17

Variables and User Inputs in Ruby

So far we’ve been seeing the utility of the data types like Strings, Numbers and Booleans. However, we wrote all of those data types directly to our IRB and that means something. When you are creating programs you’ll want to store information in some way during the execution of the program. Let’s make a simple example:

  • - Almost all of your operations need to be created with the number 50. 
  • - Why 50? Because this is the number of employees that works on the company, so you have to calculate costs, monthly salaries, and other kind of management stuff with the total number of employees
  • - Let’s say that you want to give a gift to them because it is near to December. The cost of each gift is $49. Simple operation
  • - Then is the end of the month, and you have to calculate the salary for this month. So let’s say that everybody earn the same $10.000 (hypothetically), so you multiply that number for 50 employees again
  • - Later you have to provide a t-shirt for each of the employees, because you’ll have a Saturday retreat (in a nice place with a river and a forest), which is made in the company each 6 months and all 50 employees are going to be there. The cost of t-shirt is $20
  • - Finally, the company is growing, and we’ll be hiring 5 new employees this month, so we have to calculate the salary again

We can detect something here, we’ll have to save some values in something called: Variables

Variables

Variables are used to store information to be referenced and manipulated in a computer program. They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by the reader and ourselves. It is helpful to think of variables as containers that hold information. Their sole purpose is to label and store data in memory. This data can then be used throughout your program.

In our example, what is the approximate flow of the program and the variables assignment? Let’s do some code here, open your IRB and let’s begin


2.3.3 :001 > number_employees = 50
 => 50 
2.3.3 :002 > gift_cost = 49
 => 49 
2.3.3 :003 > total_gift_cost = number_employees * gift_cost
 => 2450 
2.3.3 :004 > # $2.450 is the total cost of the gifts for the 50 employees
2.3.3 :005 >   individual_salary = 10000
 => 10000 
2.3.3 :006 > total_cost_salaries = number_employees * individual_salary
 => 500000 
2.3.3 :007 > tshirt_cost = 20
 => 20 
2.3.3 :008 > total_cost_tshirts = number_employees * tshirt_cost
 => 1000 
2.3.3 :009 > number_employees = 55
 => 55 
2.3.3 :010 > total_cost_salaries = number_employees * individual_salary
 => 550000 



As we mentioned before, a variable is a label that helps us to store data in memory. In this case the labels are “number_employees”, “gift_cost”, “total_gift_cost”, etc. Each variable is followed by the symbol “=”. This symbol means assignation, because we’re assigning a value to that variable, in the case of “number_employees” we’re assigning the value of “50”. 

One interesting thing to note here is that we aren’t doing math with numbers directly, like in the past blog post, instead we’re doing math between variables! For instance if you see the variable named “total_gift_cost” it contains the result of a multiplication between “number_employees” and “gift_cost

total_gifit_cost = 50 * 49
total_gifit_cost = number_employees * gift_cost

Two previous lines are quite different. First one we’re doing math directly, second one we’re re-using a variable previously defined. This is the most interesting part here, because this means that later in the program I can use any of these 3 variable names to do other operations and this very same variables can be assigned to other values in the future. In our case, for instance, the variable named “number_employees” changed from 50 to 55 and then we re-calculate the salary and it goes from $500.000 to $550.000 after the math (with different values)

Also we used the same variable called “number_employees” to do the math with the other variables, which is the intention of the variables itself, remember: “Variables are used to store information to be referenced and manipulated in a computer program. They also provide a way of labeling data with a descriptive name, so our programs can be understood more clearly by the reader and ourselves. It is helpful to think of variables as containers that hold information. Their sole purpose is to label and store data in memory. This data can then be used throughout your program”

Camel Case and Snake Case
The naming of the variables is something critical, because you cannot name different things with the exact same name, if so you’ll re-assigning the original value, which can cause some problems for you. So it's better to think a bit deeply about the name you want to give to that variable. 

Because of this you’ll find that it is probably better to name variables as a composed word, which means something like this: “Number of employees” or “Total cost of salaries” or “Gift cost”. As you can see we have to take a decision about the name of the variable and encode the whole name, deleting upper case words and blank spaces. Actually if you name a variable with a blank space you’ll get an error

2.3.3 :011 > number employees = 55


As you can see, we have a space between “number employees”. What the program does is to try to find the first variable name “number” and because it doesn't exist they give us a “NoMethodError” in the console.

Here is where we have other options:
  • - numberEmployees: camelCase
  • - NumberEmployees: PascalCase
  • - Number_employees: snake_case
  • - Number-employees: kebab-case

With this we eliminate the blank space, the variable is easy to understand and we won’t have any errors. The technical name for this is “Case Styles”

It seems that the differences are not worth enough, but it is. Is a good idea to choose what to use, because it is a good practice to use the same conventions over all of your programs. However sometimes the decision depends on the good practices of the language and what other people seem to do. For instance

  • Ruby and Python: in both languages are pretty common to use the snake_case
  • Javascript: is common to see programmers using a lot of camelCase


For more info, please refer to this link

Reserved words
One last thing you have to take into account when naming variables is the name itself. This is due to the fact that Ruby uses some classes and methods with a given name, and you cannot give the very same name to your own variables. This seems a bit awkward but is not, just follow the list of reserved words and at some point you’ll figure out what name convention you should use. The technical name for that words are “keywords” and here is the list of Ruby Keywords: https://docs.ruby-lang.org/en/2.2.0/keywords_rdoc.html

As you can see, it is not an extensive list and these words are reserved for doing specific tasks like declarare functions, class, conditionals and others. For this reason composed words like "number_employees" are safest to use than simple words

Let's try to use "unless" keyword as a variable and see what could happen

2.3.3 :018 > unless = "Programmer"
unless variable assignment

As we can see, we get a syntax error, because the "unless" keyword is reserved to do conditionals, so it's waiting for a block of code, not for an equal sign "=" so as a result we get a syntax error. Same thing will happen with other keywords.


User Input
So far we’ve been assigning values to the variables directly and in some way “statically”. The programs will usually need the input of the user. For instance, we can create a program that asks for the city where they live and then personalize the greeting according to the city. Here you can imagine the amount of info we can ask the user and create our programs based on that.

Let’s go to out IRB terminal again and test the user input


2.3.3 :014 > city = gets
Berlin, Germany
 => "Berlin, Germany\n" 
2.3.3 :015 > city
 => "Berlin, Germany\n" 
2.3.3 :016 > city = gets.chomp
Medellín, Colombia
 => "Medellín, Colombia" 
2.3.3 :017 > city
 => "Medellín, Colombia"




We can see two new things here:
  • gets
  • gets.chomp

gets” as the name suggests it gets the user input and then that value is assigned to the variable named “city”. When you type the first line of code the IRB keeps waiting for you to type something with your keyboard & press the enter key. Once you give the value and hit enter, we get the output. However this output seems a little weird, because at the end of my input it places this symbol “\n” which represents the enter key. But we don't want that as part of our string. We'll use chomp chained to get rid of that - you can put .chomp after any string to remove the carriage return characters at the end.

gets.chomp” the only way to get rid of that special character is adding .chomp at the end. Chomp is a String class method in Ruby which is used to return a new String with the given record separator removed from the end of str (if present). chomp method will also removes carriage return characters (that is it will remove \n, \r, and \r\n) if $/ has not been changed from the default Ruby record separator, t

With this we have a first visual about variables and user input

I hope you learned a lot

Thanks for reading
DanielM