Advice for Ruby Programming Foundations Written Assessment(Part 3)

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

Variable Shadowing

Without running the code try to answer what will this code example output :

Result → This code outputs 5, 5 , 4 and2 in this order.

This one is a bit tricky so let’s break it down and see what is happening.

On line 1 we are initializing the local variable a and setting its value to 4.

On line 2 we are initializing the local variable b and setting its value to 2.

Now comes the tricky part. On line 4 we are calling thetimes method on integer 2 and passing in thedo..end block as an argument with one parameter a .

What is happening on line 5 ? We are reassigning the local variable a that was initialized in the outer scope right? Not really… This is the concept called variable shadowing and it happens when parameter name of the block is the same as the name of the local variable which was initialized outside of the block. The consequence of the variable shadowing is that it prevents access to variables of the same name initialized outside of the block. So on line 5 we are actually assigning integer 5 to the local variable a passed in as a parameter of the do..end block and the value of our local variable a initialized in outer scope remains 4.

The rest of the code is pretty self explanatory. Inside of the do..end block we are calling theputs method and passing the local variable a as an argument (this is the local variable passed in as a parameter and assigned to 5 so this code outputs 5 and 5 . Line 9 outputs 4 since the local variable a wasn’t changed as I explained above, and thefinal output 2 is easy.

How could we fix this code so it actually reassigns local variable a inside of the do..end block? Easy enough. Just change value of parameter to anything but the a . In that case the code would output 5, 5, 5 and 2 as shown below…

If you are wondering I have used underscore as parameter name on line 4 , the reason is, whenever you are not using a certain parameter that you have passed to the block as an argument the common practice is to name it _ .

Each, Map and Select methods

First, to understand these methods well I am suggesting this great video from Launch School.

Let’s explain now what Array#each , Array#map and Array#select methods do.

First we will start with Array#each method and this simple example :

[1, 2, 3, 4].each { |num| puts num }

So, what does this method do? It iterates through the array object passing each element of the array to the block, runs the block (in this case outputting value of parameter num) and when it finishes every iteration it returns the original array. So, each method doesn’t care about return value of the block. Do you know what the return value of the block is after each iteration? If you don’t no worries I will explain it in the next example.

[1, 2, 3, 4].map { |num| puts num }

What Array#map does? It also iterates through the array object passing each element of the array to the block, runs the block and here is where these two method start to differ. Map method actually takes return value of the block and moves it into a new array and when it finishes every iteration it returns that new array with elements which were passed in it (return values of block of each iteration). So what is return value of the block after each iteration? Is it the number that is passed in as parameter? Nope, since we are calling method puts inside the block, and remember that method puts always returns nil so our example above would return a new array [nil, nil, nil, nil]. It would output all of this values from the original array, since puts method is called, but the return value of map method call would be this array of nil.

Finally, what about Array#select ?

[1, 2, 3, 4].select { |num| puts num }

Like each and map , select method also iterates through the array object passing each element of the array to the block and runs the block. What select method does differently now is, it considers does the return value of the block evaluates to true or not and if it does it takes that element and puts it in new array. You can see that I have made word evaluate bold and that’s because this word is very important. Everything in Ruby evaluates to boolean true except false and nil. So, let’s consider this conditional :

if 3 … is it true? No it’s not. 2+3 == 5 would be true but if 3 is not true, it evaluates to true since it is not false or nil. Be aware of that, and don’t forget to say that select method considers if the return value evaluates to true or not.

So, as I have said already, select method evaluates return value of the block during each iteration and if it evaluates to true moves that element into new array, and if it doesn’t evaluate to true, it doesn’t do anything. What will be the return value of our code above then? It would be empty array since during each iteration return value of the block evaluates to false so none of the elements of the original array would be put into new array and we are left with an empty array.

Continue to part 4…

--

--