These free mini-courses will give you a strong foundation in web development. Track your progress and access advanced courses on HTML/CSS, Ruby and JavaScript for free inside our student portal.
Scroll down...
Ruby can be used to solve all sorts of interesting problems and it contains a whole lot of different helper methods to get you there. In fact, there are so many interesting methods for doing things like manipulating arrays or iterating that beginners often end up either confused or coming up with some odd ways of doing things.
In this quick lesson, we'll just cover a few very basic situations and how you should approach them with Ruby. This is intended to cut through the noise when you're approaching simple logical problems like the ones you'll see in the coming assignment and during the VCS application process.
Name your variables descriptively. That should be the end of the discussion but sadly beginners seem to love to use names like i
, counter
, array
, or num
. What do these variables represent??? Every problem has some sort of real-world context -- your variables should be named to reflect it! It will help you enormously to keep from getting lost inside your problem. This comes from experience.
Don't worry about making your names too long when you're first starting out. It's better to be too descriptive and eventually pare it back than to use garbage like i
unless there's absolutely no better way.
Just about everything starts at 0 instead of 1. This is a common programming convention. The times
iterator starts at 0. Array indexes start at 0. The each_with_index
iterator starts at 0. Just assume something starts at 0 unless you're sure otherwise!
Focus on indenting your code properly. Everything that opens up a new loop, block, or logic chain (ie. anything that finishes with an end
) should be indented. It doesn't just look terribly amateurish to have poorly indented code but it also makes it MUCH more difficult to figure out why you're getting odd errors.
The bottom of your code will probably look like it's got a cascade of end
s.
def some_method
some_array = []
4.times do |i|
if some_condition
# do something
else
# do something else
end
end
some_array
end
It's okay to start off using four spaces or a tab when indenting (as long as you're consistent). Try to start using 2 spaces instead when you get better at reading code (it's more conventional).
"I need to do something some number of times, so I think I'll set up a triple nested looping structure using three different iterators all with the same variable i
" -- we've seen this more than once
Beginners often find 1001 different ways to iterate. You really only need to know 3 or 4 for right now. And very few people use for
loops in Ruby, so you can mostly forget about that. The key to iteration is to KEEP IT SIMPLE! Just use the most basic iterator that covers what you want to do.
When you know exactly how many times you want to iterate through something, just use the times
method:
def three_cheers
3.times do
puts "Hip Hip, Hooray!"
end
end
A more common situation is iterating through each item in an array or hash (this comes up a lot when working with data in web applications) without actually modifying any of those items. Luckily, Ruby has the simple each
method:
# Read an array that represents a list of groceries
def read_grocery_list(grocery_list)
grocery_list.each do |grocery_item|
puts "buy #{grocery_item}"
end
end
# What our script looks like when run in IRB:
> read_grocery_list(["tomatoes","lettuce","dressing","milk"])
buy tomatoes
buy lettuce
buy dressing
buy milk
=> ["tomatoes", "lettuce", "dressing", "milk"]
You might need to run operations that rely on knowing the "current" position in your iteration, so you could also use each_with_index
, though this is more rare:
# Read an array that represents a list of groceries
def read_grocery_list_intelligently(grocery_list)
list_length = grocery_list.size
grocery_list.each_with_index do |item, position|
if position == 0
puts "Start by buying #{item}"
elsif position == list_length - 1
puts "and, finally, buy #{item}."
else
puts "then buy #{item}"
end
end
end
# Run the script in IRB:
> read_grocery_list_intelligently(["tomatoes","lettuce","dressing","milk"])
Start by buying tomatoes
then buy lettuce
then buy dressing
and, finally, buy milk.
=> ["tomatoes", "lettuce", "dressing", "milk"]
If you want to actually collect a new array filled with modified items of your original array, then you'll use the map
method instead. For solving simple logical problems, this is again not terribly common (it's more often used with database data and things like that).
When looping as long as some condition is true, use a while
loop. BUT -- you usually know exactly how many times you need to iterate, which would call for one of the methods above. while
is most useful for more complex problems like games which want to continue looping until someone has lost:
def play_game
while player_1.lives > 0
# Do stuff to play game
end
end
There are a LOT of random string, array and hash methods out there. You of course need to be good at creating strings, arrays and hashes and accessing specific items inside of them, but there aren't a whole lot of other methods that you'll frequently encounter.
Creating Strings, Arrays, and Hashes:
> my_string = "some string here"
> my_empty_array = []
> my_full_array = [item1, item2]
> my_empty_hash = {}
> my_full_hash = { :key1 => value1, :key2 => value2 }
Be sure to understand include?
for checking if an item is in an array:
> ["go","to","sleep!"].include?("sleep!")
=> true
And split
for breaking apart strings into arrays:
> "go! to! sleep!".split("! ")
=> ["go", "to", "sleep!"]
And the opposite join
for turning arrays back into strings:
> ["go", "to", "sleep!"].join(" ")
=> "go to sleep!"
You might occasionally want to know WHERE inside an array the item is with index
:
> ["go","to","sleep!"].index("sleep!")
=> 2
Other position methods like first
or last
are useful too, as well as some pretty self-explanatory ones like max
and min
.
To add items to an array, you can just shovel them in there with the shovel operator <<
:
> ["just one item"] << "another item"
=> ["just one item", "another item"]
If you want to just look at or modify the last item, you can index backwards from the end of the array. -1
is the last item, -2
is the second to last, etc. If you actually want to remove the last item, just pop
it off. The alternative, push
, acts like the shovel operator above.
> my_arr = [].push("first one in!").push("second!") << "Thirdsies!"
=> ["first one in!", "second!", "Thirdsies!"]
> my_arr[-1]
=> "Thirdsies!"
> my_arr.pop
=> "Thirdsies"
> my_arr[-1]
=> "second!"
Make sure you know what your methods are returning. Just about everything in Ruby is a method and methods always return something (or nil
). Some common things that trip up beginners:
return
statement given. If your method is returning something weird, it's probably because you're not properly thinking about this.each
returns the original array. This is the most commonly forgotten fact.puts
returns nil
. This is the second most commonly forgotten fact.map
returns the modified array.Instead of typing everything on the command line with IRB, try storing your ruby code in a .rb
file. Put a line at the end which actually executes any methods you want to execute and then run it from the command line using the normal $ ruby your_file.rb
.
# file located at my_script.rb
# Your method
def say_hi
puts "hi"
end
# Run the code
say_hi
# On the command line
$ ruby my_script.rb
hi