What Happens in Method, STAYS in Method!

Flatiron School / 21 October 2013

The following is a guest post by Edina Vath and originally appeared on her blog. Edina is currently in the Ruby-003 class at The Flatiron School. You can follow her on Twitter here.

Well, except global variables, and the return value, and… mmmkay, so whatever happens in method doesn’t always really stay in method but let’s talk scope anyways. FYI the other slogan, the Vegas one, that isn’t quite true either. The hangover definitely does not stay in Vegas, but your MONEY totally does.

If you are just starting out with programming you will very quickly run into the issue of scopes. I will talk about methods, loops and blocks. But not in this order.

Let’s start with loops. Loops do not create a new scope. Whatever you swiftly declare before the loop will be accessible and modifiable inside, and will come out modified after your looping is done. Lets look at a simple example:

after the loop
this will have the value of 5
that will have the value of 6
you can also declare new values in loops and those pesky little things will stick around after your looping action is done

after the loop 
x will have a value of 3 and new will still have the value of 2
Easy breezy. Let’s step it up and move over to blocks. Blocks have kind of like a one way scope. You can grab values from the outside and play around with them in your block but if you create new variables inside your block they will only stay alive for couple of milliseconds then they die when the block terminates. How sad. Let’s kill some borg.

after the block enterprise will be "awesomeawesome" and borg will be NameError: undefined local variable or method 'borg' for main:Object cause you know, they are in the black hole. So you see your block can handle input from the outside but cannot declare new permanent variables. Don’t forget that your block will have a return value (just like everything (EVERYTHING) in Ruby) which could help you if you would like to save 7/9 from the borg. I would recommend that you read the ruby-docs on and other iterators to fully understand what certain blocks return.

here the map will return the modified array ['7/9'] but still this will only last for a blink of an eye before our program moves on to more important stuff to do. Let’s save the return value into a variable.

now saved_borg will hold ['7/9'] and we can move on with out adventures to planet method.

I like to think about methods as mini prisons for my variables. The only way something goes into my method if I explicitly send it in and uhm… it kinda won’t get out…? It is a very shady prison now that I think about it. Only one thing gets out of my methods (the return value) and I will carefully chose what that is.

While this method is fun realize that the meal variable will not get changed. After we call our method we will have a return value (either the meal itself or “emtpy_tray”) and meal will still equal "unrecognizable gel-like substance".

We pass in the meal, to decide IF gross or not. But when we step into the ELSE branch in our method the meal = "eaten" expression will create a new local variable. This variable has nothing to do with the meal existing outside of the method other than having the same name. It is a local variable, has no scope outside the method and it will disappear the instant we return anything. We can change our passed in values and use them for operations inside but these changes will not be permanent or even visible from outside. It is like prison! People go in spend couple of years inside doing God knows what (okay, we do know what they do, they work for pennies a day making helmets for the military, slavery anyone?), then they come out and nothing really changed… Yes our prison system sucks but honestly methods in Ruby are awesome and they totally get the job done. Let’s look at another example and let’s ditch the prison allegory before I make you totally depressed.

after calling the method
the value of x will be still 1
the value of y will be still 1
Now our method returned 2000. So what? Nothing. What happens inside my prison is hush hush. (ahh, okay seriously I am done with the prison) Just for fun we could save the return value into a variable

Now we would have z holding the value of 2000 (Methods will always return the last value or the end result of the last operation they did).

Are you getting this? Yes? Good. But be careful, be careful. If you pass in an array to a method, you can modify that array from inside the method.

after calling the method
z will have equal to [1,2,3,9,8]
push will modify hashes and strings too

after calling the method
str will have a value of "monkey"
Wait, why? – you might wonder. This has to do with destructive / non-destructive methods in Ruby. Push and pop (along with the bang methods) are called destructive methods because they modify the original object they are called on. Variables in Ruby are essentially pointers that have the address for their object. Non-destructive methods such as gsub will will create a new modified string after it is called on a variable, while the destructive version gsub! will modify the original object.

Let’s see an example from 24. We have two bombs! OMG! Time is counting down and we only have ten seconds left! ZOMG again! But fear not, our specialist is here to tap into the bomb’s software and save the day. Hopefully he read this blog post and knows what’s the difference between the two methods.

which method should he call?
if you call the keeps_ticking_away the time will just keep counting down in the body of our program. If you call defused_bomb however that bang method will actually change the value of the time object to "99990". Ton of time to figure out if you need to cut the blue or the red….

We learned today that
* Loops don’t create a new scope
* Blocks are kind of one way streets
* Methods have their own method scope which is a very tight bubble
* There are two kinds of methods destructive and non-destructive
* Jack Bauer needs to learn Ruby 

What's Foo Bar? Previous Post Modules, Classes, Pterosaurs Next Post