Scoping Out Method Scopes

I have finally returned to Ruby and none too soon! Today, lets look at scopes in Ruby.

The scope of a program means that the variables we create do not exist everywhere in a program. This helps in preventing the programmer from overwriting a variable created by someone else (or, let’s be honest, themselves) in other parts of a program. I mean, it could still happen, but it reduces the risk.

Methods have their own scope. A variable created outside a method is unavailable to the method. This means if we set a variable outside of a method, and then create a method with variables inside that method, the variables outside the method are not accessible inside the method and vice versa. Let’s look at an example:

Now, in the above I have defined a variable outside of the method, my_name, and set it equal to Nick. When I run the Ruby file I get the immediate response below the defined method, #greeting, that puts the my_name variable to the screen. It also returns nil. Below that I call the #greeting method and pass in the argument “Sophie” which runs and spits out an error.

See here:

So, we see that outside the method that my_name variable is accessible. Inside the method, however, my_name is inaccessible. Let’s try something a little different. What if I have this?

What will happen? If you run the file, my_name variable will be puts to the screen and then we get an error. See here:

At this point the program stops, thus #greeting method is never called. Why? Because inside_voice is a method scope variable and inaccessible outside of it.

Completing Object Oriented Tic Tac Toe!

It is always satisfying when you get to the end of something. There is a sense of satisfaction and maybe even a bit of apprehension. That is what I can say as I came to the end of the Introduction to Ruby at Flatron School. I can say two things with certainty:

  1. I never thought I would be challenged this much with Tic Tac Toe.
  2. I still don’t feel 100% confident with Ruby. 🙁

I mean, I feel much better with it than I did coming in. I had done some study with it at Treehouse, and the Learn Ruby the Hard Way book from Zed Shaw. Flatiron challenged me. I nearly broke me at times, as anyone following this journey can attest to.

And that was the intro.

In any case, part one is over. As such, this post is going to delve into reviewing the last part of the intro to Ruby: Object-oriented Tic Tac Toe.

To begin, its probably imperative to explain the difference between procedural Ruby and Object-oriented Ruby. I understood it like this.

In the procedural approach, we wrote a series of methods and had the data laying there at the beginning by itself. We then, in a step by step approach, acted on the data. It was not organized into anything, and could be haphazard in how it is handled. We have to know what is happening to the data as we go down the list of procedures. In the procedural version of tic tac toe, we acted on the board array. If we have a procedure that affects it in a way we don’t account for, the next step could break or cause us any number of issues.

In the object oriented approach, the object we create acts on its on data. Inside the object, the data and methods are all bundled together. To see the end result of the procedural tic tac toe, check here. Now, let’s look at the object oriented approach!

First, I’ll lay out my code:

This is the bin file:

And here is the Ruby file:

So, to understand what is happening, we need to start with what a class is. Flatiron decribed it as a blueprint used to build an object. So, we are creating a blueprint here of what a Tic Tac Toe game is. This entire object is the Tic Tac Toe game. When, in the bin file this is called:

It is creating an instance of the Tic Tac Toe game that loads everything needed to play the game until a victor is crowned or it ends in a draw.

I won’t go over everything inside this as it will probably look familiar. There is a big difference, however, in that the board array is created here:

and then passed around inside the object. I will admit to being confused on the argument being passed in here. Flatiron presented this as:

But when I went and built it I just created the board as the Array with 9 empty strings. I did not, and still don’t, understand why the “or” statement is needed here. What is confusing is the need for the argument being (board = nil). I tried doing it with only board passed in and it broke the whole thing…

And this is the error I was given:

I mean, I passed in board still. Why does it need to be nil? In any case, being nil works for it, and who am I to argue…

Now, some things to note. @board is an instance variable. This allows it to be passed around from method to method inside this object. We are creating it inside a special method in Ruby called #initialize which allows us to create certain attributes inside our instance. Every game of Tic Tac Toe needs a board. the board is used throughout this object, so it is best to create it here. Notice though that once we create it here, we don’t need to use it as an argument throughout the rest of the object. Let’s compare the #display_board methods from procedural and object oriented approaches:

Procedural:

Object Oriented:

Notice in procedural that board needs passed in as an argument. You create the argument and then pass it in. In the object oriented approach, we create it in the #initialize method, and now it just needs called. Notice where it is called throughout. We do still have arguments in the other methods, but where board would have needed called, I used the instance variable.

There are two other methods that I should take a minute to look at as they were interesting. Again, the comparison helps here:

Procedural

Object Oriented:

These were tricky and it was because I forgot that in the procedural approach that when i used a helper method I have to pass in its arguments also. In the object oriented approach, the @board instance variable is again already there. The object is handling that data, so you just need to call the method and let Ruby handle the rest!

Otherwise, this lab was pretty straightforward. Wherever the local variable board was in the procedural approach, I replaced it with the @board instance variable, removed it from the arguments and then it worked. Honestly, I was expecting a few days of hell, so I’ll take it.

Day 47: Applied to LaunchCode and Getting Help at CodeNewbie Slack Channel

So, my original plan was to start JavaScript tonight. Instead, I ended up applying to LaunchCode and starting their test by mistake, scrambling to answer at least one question and then learning how to use the .reduce method to solve the hole math problem. Let me explain.

I have been wanting to find a job where I can start learning more daily while using the skills I have now as best I can. I came across LaunchCode and decided to apply. While I selected I would be willing to relocate to St. Louis, I would still prefer to stay close to where I am now. I answered the other questions on the application like so:

Please tell us how your interest and experience in technology progressed.

When I first left high school, I was working tech support at a local internet service provider in New Bern, NC. I found this job after working for 6 months running a movie theater and not really liking the experience. I knew very little about computers at the time and before the interview, I read up and learned as much as I could. I have had a love of computers since. I never thought I could be a programmer but recently I have found myself longing for a career in tech and decided to try it out online. I love it! I rush home daily to study more each day and I am tracking my progress on a blog. Between my first tech adventure and now, I have had many sites online through WordPress or others. I now have found something I am passionate about!

Tell us about a project you have worked on that you take a great deal of pride in. Provide links if available.

I recently completed my first program ever in Ruby. It is a book tracking app that prompts the user to enter the book, author, whether they read or listened to it and then a short, one sentence review. I am extremely proud of the app. I learned how to write loops, I learned to use YAML to save information between sessions and I learned how to search for answers on Google which is invaluable. Most importantly, I learned that I can do this, and had a lot of fun in the process. I blogged about the experience at nickqueen.com. It is located here: https://github.com/demosthenes131/book_tracker

Day 38, Part 1: First App Finished

I just finished my Book Tracker app. I decided to only add a print function as I would want to put out the whole list as I go. I may go back eventually to add search, but for what it is for I believe a list function is best. I am using it to track as I go.

I created a video to detail the app and show how it works:

and here is a look at the code. You can also see the code at my GitHub profile.

First, the main file:

and the the file where I create Book.class:

and then the YAML file… where the data is stored.

OK, I am moving on to Ruby on Rails tonight. I will return shortly!

Day 37: Working on my App and Finishing Exercise 39 at Learn Ruby the Hard Way

I had a day off from work so spent a good portion of the day enjoying being off work. I am back now to finish the long lesson last night from Learn Ruby the Hard Way: Exercise 39: Hashes, Oh Lovely Hashes.

So, the second portion of the Exercise had a module, dict.rb, and then another file full of hashes to run using the module. Here is the code:

and the test file:

demosthenes131@rails-tutorial:~/workspace/LRTHW (master) $ ruby ex39_test.rb
———-
NY State has: New York
OR State has: Portland
———-
Michigan’s abbreviation is: MI
Florida’s abbreviation is: #Dict.get(states, ‘Florida’)}
———-
Michigan has: Detroit
Florida has: Jacksonville
———-
Michigan
MI
New York
NY
Florida
FL
Oregon
OR
California
CA
———-
CA
San Francisco
OR
Portland
NY
New York
MI
Detroit
FL
Jacksonville
———-
Sorry, no Texas.
The city for the state ‘TX’ is: Does not exist

And now back to my app!

I added a way to preserve added data today via YAML

Here is the BookTracker main file:

the Book class file:

and what happens when I add information:

First session:

demosthenes131@book_tracker:~/workspace (master) $ ruby book_tracker.rb
Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
a
Book title: Storm Front
Author: Jim Butcher
Genre: Urban Fantasy
Have you read it, listened to it, or is it a wish list item? Listened
Write a short, one sentence, review! Amazing
Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
e
[#]

At this point I was having a lot of trouble originally. Everytime I restarted the app and entered a new book the previous book was deleted. I fixed this by adding the open() to the run method which would then populate the array. Next session after this (also after I removed a few items that I will re-add later):

demosthenes131@book_tracker:~/workspace (master) $ ruby book_tracker.rb
Select an option from the below choices
a: Add a Book
e: Exit
a
Book title: Hounded
Author: Kevin Hearne
Genre: Urban Fantasy
Have you read it, listened to it, or is it a wish list item? Read it
Write a short, one sentence, review! Fun
Select an option from the below choices
a: Add a Book
e: Exit
e
[#, #]

And here is the YAML output file:

My plan tomorrow is to work on the search and print functions!

Day 36: Splitting Time Between Writing a New App and Learning Ruby the Hard Way

So, I want to get back to finishing Learn Ruby the Hard Way while also applying my new found knowledge to the app I am creating.

I will start with Exercise 39:

and the results:

demosthenes131@rails-tutorial:~/workspace/LRTHW (master) $ ruby ex39.rb
———-
NY state has: New York
OR state has Portland
———-
Michigan’s abbreviation is: MI.
Florida’s abbreviation is: FL
———-
Michigan has: Detroit
Florida has: Jacksonville
———-
Oregon is abbreviated OR
Florida is abbreviated FL
California is abbreviated CA
New York is abbreviated NY
Michigan is abbreviated MI
———-
Oregon has the city OR
Florida has the city FL
California has the city CA
New York has the city NY
Michigan has the city MI
———-
Oregon is abbreviated OR and has city Portland
Florida is abbreviated FL and has city Jacksonville
California is abbreviated CA and has city San Francisco
New York is abbreviated NY and has city New York
Michigan is abbreviated MI and has city Detroit
———-
Sorry, no Texas.
The city for the state ‘TX’ is: Does Not Exist

OK, I have more to do this lesson but spent the rest of my night reading through my code and trying to figure out how to get my user input to go into a hash then have that hash go into an array. I will continue tomorrow.

Day 35: Getting Closer to a Finished First App

So, i made more progress today, especially thanks to Jesus Castello of BlackBytes.info who helped me understand the difference between instance vs. local variables. So, here is how the Book Tracker is looking tonight. Also, feel free to take a look at it on GitHub.

The book class:

and the main book_tracker file:

And here are the results for this:

Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
a
Book title: Ender’s Game
Author: Orson Scott Card
Genre: SciFi
Have you read it, listened to it, or is it a wish list item? read it
Write a short, one sentence, review! Awesome
Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
a
Book title: Storm Front
Author: Jim Butcher
Genre: Urban Fantasy
Have you read it, listened to it, or is it a wish list item? listened
Write a short, one sentence, review! Amazing
Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
p
Book List
#
#
Select an option from the below choices
a: Add a Book
p: View the Books
s: Search the Books
e: Exit
e
[#, #]

I will continue hacking away tomorrow!

Day 34 Update: Working more on the App

OK, so I did some more work tonight. I am just going to post the files as they are a work in progress. Still not working 100%.

This is my new class for Book.

and the book_tracker main file. Its a mess as I am still trying to figure out how to store the data and scuh. The array is still not working, though it was earlier. I will keep working on it.

I will keep on working on it all.

Day 33: Making the Decision to Write My First App

Well, I have made a decision. I will be writing my first app over the coming days (possibly weeks).

I have decided to make an app in Ruby to track books I have read or listened to. I would like to eventually be able to assign a short, one sentence review to each. I would also like to figure out a way to mark the books as read, listened to, or wish list. Let’s get started.

Preface: I will be borrowing code from previous exercises. I will make a lot of mistakes. I will not apologize for either. I will say thanks to the previous exercises, however.

OK, here goes. The first bit of my code adds a menu that barely works and allows me to add a book.

OK, this is what happens:

demosthenes131@book_tracker:~/workspace $ ruby book_tracker.rb
Select an option from the below choices
a: Add a Book
v: View the Books
s: Search the Books
e: Exit
a
Add a book!
Ender’s Game
Select an option from the below choices
a: Add a Book
v: View the Books
s: Search the Books
e: Exit
a
Add a book!
Old Yeller
Select an option from the below choices
a: Add a Book
v: View the Books
s: Search the Books
e: Exit

Weird. It won’t keep the previously entered book. I need to create an array to collect these, I’m guessing…

And I have banged my head for an hour on this. I scrapped the whole thing and went simple:

and the results:

demosthenes131@book_tracker:~/workspace $ ruby book_tracker.rb
Add a book!
Ender
[“Ender”]
Add a book!
Shadow
[“Ender”, “Shadow”]
Add a book!
Hitchhiker
[“Ender”, “Shadow”, “Hitchhiker”]
Add a book!
Dresden
[“Ender”, “Shadow”, “Hitchhiker”, “Dresden”]
Add a book!

OK, this works. Let’s go a little more fancy. I want it to loop until I end it, and allow me to enter as many books as I decide. When I end it, I want it to print the list of books and then break. I worked it out a bit:

book_list = []

and it works! I was as surprised as you are:

demosthenes131@book_tracker:~/workspace $ ruby test.rb
Do you want to add a book? (yes or no)
yes
Add a book!
Ender’s Game
Do you want to add a book? (yes or no)
yes
Add a book!
Dresden Files
Do you want to add a book? (yes or no)
yes
Add a book!
Hitchhiker’s Guide to the Galaxy
Do you want to add a book? (yes or no)
no
[“Ender’s Game”, “Dresden Files”, “Hitchhiker’s Guide to the Galaxy”]

I also want to be able to add a one sentence review. I think a hash would work for this. Here is my attempt:

And the results:

demosthenes131@book_tracker:~/workspace $ ruby test.rb
Do you want to add a book? (yes or no)
yes
Add a book!
Ender
How about a short, one sentence review? (yes or no)
yes
Add your review!
Great book!
Do you want to add a book? (yes or no)
yes
Add a book!
Dresden
How about a short, one sentence review? (yes or no)
yes
Add your review!
Lots of fun
Do you want to add a book? (yes or no)
no
[“Ender”, “Dresden”]
{“book”=>[[“Ender”, “Dresden”]], “review”=>[[“Great book!”, “Lots of fun”]]}

I tried to work out the way to display this right. No luck as of yet. My last update:

and the result:

demosthenes131@book_tracker:~/workspace $ ruby test.rb
Do you want to add a book? (yes or no)
yes
Add a book!
Ender
How about a short, one sentence review? (yes or no)
yes
Add your review!
Awesome book
Do you want to add a book? (yes or no)
yes
Add a book!
Dresden
How about a short, one sentence review? (yes or no)
yes
Add your review!
urban fantasy fun!
Do you want to add a book? (yes or no)
no
[“Ender”, “Dresden”]
{“book”=>[[“Ender”, “Dresden”]], “review”=>[[“Awesome book”, “urban fantasy fun!”]]}
book – [[“Ender”, “Dresden”]]
review – [[“Awesome book”, “urban fantasy fun!”]]

Day 33: Back to Learn Ruby the Hard Way (Part One)

I am back and learning Ruby the Hard Way. Let’s get to it. I am skipping ahead a bit as Exercise 36 was to work on a RPG game and Exercise 37 was memorizing symbols. I am working on a different project soon to add to my portfolio. I am also adding the symbols to AnkiDroid for study. So, I am doing Exercise 38: Doing Things to Arrays.

Here is the code we are starting with:

and the results:

demosthenes131@rails-tutorial:~/workspace/LRTHW (master) $ ruby ex38.rb
Wait there are not 10 things in that list. Let’s fix that.
Adding Boy
There are 7 items now.
Adding Girl
There are 8 items now.
Adding Banana
There are 9 items now.
Adding Corn
There are 10 items now.
There we go: [“Apples”, “Oranges”, “Crows”, “Telephone”, “Light”, “Sugar”, “Boy”, “Girl”, “Banana”, “Corn”].
Let’s do some things with stuff.
Oranges
Corn
Corn
Apples Oranges Crows Telephone Light Sugar Boy Girl Banana
Telephone#Light#Sugar

So, in this exercise we are seeing how to add items into the array, as well as count the items inside it.

Study Drill time:

1. Translate these two ways to view the function calls in English. For example, more_stuff.pop() reads as, “Call pop on more_stuff.” Meanwhile, pop(more_stuff) means, “Call pop with argument more_stuff.” Understand how they are really the same thing. and 2. Translate these two ways to view the function calls in English. For example, more_stuff.pop() reads as, “Call pop on more_stuff.” Meanwhile, pop(more_stuff) means, “Call pop with argument more_stuff.” Understand how they are really the same thing.

I am going to combine these. Let’s take a look:

Take the ten things and split them up with a space.

While the list of stuff is not 10, take items and add them until there are 10.

Let’s call things from the array in various ways:

The item at cardinal number 1 is Oranges.
The last item is Corn
Pop the last item of the array off, which is Corn.
Join all the items together using a space and list them here.
List the items at cardinal numbers 3 4 5 and join them with a #.

3. Go read about “object-oriented programming” online. Confused? I was too. Do not worry. You will learn enough to be dangerous, and you can slowly learn more later.

I decided to find a simple explanation for now. Take a look here.

4. Read up on what a “class” is in Ruby. Do not read about how other languages use the word “class.” That will only mess you up.

This was taught at length over at Treehouse!

5. Do not worry If you do not have any idea what I’m talking about. Programmers like to feel smart so they invented object-oriented programming, named it OOP, and then used it way too much. If you think that’s hard, you should try to use “functional programming.”

I enjoy this.

6. Find 10 examples of things in the real world that would fit in an array. Try writing some scripts to work with them.

Hmm. I mean, a lot of things can be used in an array. I will do one example as I worked with these at length at Treehouse.

and the result:

demosthenes131@rails-tutorial:~/workspace/LRTHW (master) $ ruby studydrill38.rb
The best breed of dog is the Jack Russell Terrier.
Jack Russell Terrier * Poodle * German Shepherd * Collie * Pug

OK, be back a little later.