Flow of Execution
Learn about the flow in which Ruby runs our code.
We'll cover the following
Feel free to skip this chapter if you understand Ruby’s program flow, defining and calling a method, returning from it, perhaps calling another method, and so on. We’ve discussed this before. Because this is a potentially confusing topic, we’ll go over it again.
Note: It’s easy for programmers to forget to explain to beginners how Ruby flows through a program and in what exact order. This is called the flow of execution, or control flow.
When we execute a Ruby file (with the ruby runtime
), it reads the Ruby code and executes it line by line, from top to bottom.
Example
Let’s look at our example from before, and how the Ruby control flow goes through it, in greater depth.
We’ve added parentheses for the method call to puts
to make this more obvious, even though we recommend against this in practice:
def add_two(number)number + 2endputs(add_two(3))
Ruby flow of control
-
Ruby starts on line 1 and finds our method definition, starting with the
def
keyword. It reads everything until it finds theend
keyword on line 3. For now, it does nothing but define this method and keep it in memory so that it can be used later. -
In line 4, Ruby finds that we’re using the
puts
word, and it sees that we’re trying to pass something to it, so this must be a method call. -
To call a method, Ruby needs to first evaluate the values that we want to pass. So, Ruby looks at what’s between the parentheses and finds another method call,
add_two(3)
. -
Again, to call the method,
add_two
, Ruby needs to first evaluate the values that we want to pass. In this case, this is the number 3, so Ruby creates this object (an instance of the classNumber
). Now, it’s finally ready to call theadd_two
method, passing the number just created. -
For the first time, Ruby starts to deviate from the default flow of execution, which simply goes from top to bottom. Instead, because we’re calling a method, Ruby enters the method body that we defined for the
add_two
method before. Control flow now jumps to line 2. -
In this moment, since we are entering a method that has an argument, Ruby also defines a local variable
number
, and assigns the object that was passed, the number3
, to this variable. -
Because we’re entering a method with an argument, Ruby also defines a local
number
variable and assigns the object that was passed, the number3
, to this variable. -
Now, Ruby is ready to evaluate line 2. It finds that we’re using the
+
operator on the value assigned to thenumber
variable, which is3
. To do that, Ruby first evaluates what’s on the right-hand side of the operator, which is a number in our example. Ruby creates the number (an instance of theNumber
class), this time with a value of2
. -
Ruby is now ready to evaluate the operator and adds the number
2
to the number3
. This operation returns a new number (an instance of the Number class), which is5
. -
Ruby recognizes that the method body has ended, so it returns
5
from theadd_two
method because this was the return value of the statement that was evaluated last. -
The control now jumps again to line 4. Ruby is now done evaluating the method call
add_two(3)
, which returns5
. Ruby can now finally call theputs
method, passing the object5
, which Ruby then prints out.