Ruby Tutorial
Ruby Tutorial
If you have decided to learn Ruby & become a Ruby developer then you're
in the right place.
You have a lot of learning ahead of you, but don't let that stop you from
getting started.
Now:
You'll find a lot of new words in your journey, don't worry about that,
you'll learn along the way.
The reason I'm telling you this is because I don't want you to give up early if
you're seeing a lot of error messages & if things don't make a lot of sense.
These things are normal, you are learning something new & it's going
to take some time until it starts to sink in.
Work on every topic until you understand how it's useful in the big picture,
how to use it, how to explain it to other people.
If you are using Windows you want to go to this site to download Ruby:
https://rubyinstaller.org/downloads/
You want the recommended version, which at the time of this writing is
Ruby+Devkit 2.4.4-2 (x64).
Now to start writing your Ruby programs you will need to open a
terminal.
At this point you should be able to type ruby -v inside this window & get
the current version of Ruby printed in there.
Ruby Setup For Linux & Mac Users
If you are on Linux or MacOS then you probably already have Ruby installed.
You can confirm this by opening a terminal (search for "terminal" in your
menu), then typing ruby -v.
Like this:
If you don't get a Ruby version then refer to this site for more details on how
to install Ruby for your particular Linux version or Mac.
Let's Write Some Code!
Now that you are set up, I want you to open irb.
This is a Ruby program that allows you to type Ruby code & see the results
right away.
To open irb you have to type the word irb inside that black terminal
window I had you open before.
Press enter.
irb(main):001:0>
5 + 5
Of course.
The point of this is to get you used to typing inside the terminal window.
And you're going to be using numbers a lot inside your Ruby programs:
To count things
To access information
Now it's time to practice!
10 * 2
500 / 100
1 + 2 + 3 + 4 + 5
Also I want you to close your terminal window, open it again, open irb &
type more math.
...a name for something that you can use to reference this value in your
Ruby programs.
age = 32
Now when you type age Ruby will translate that into 32.
Try it!
You could use bacon = 32 & the value would still be 32.
Using Variables
age * 10
# 320
age = 32
multiplier = 10
age * multiplier
global variable
instance variable
class variable
constant
You don't need to worry too much about these right now, but it's good to
know they exist.
This is only going to matter when you start learning about Object-Oriented
Programming, we'll revisit this topic by then.
Practice Time!
Now:
This concept of variables is very useful, if you don't use variables you
would have to repeat every single calculation every time that you want to
refer to it.
And you wouldn't have a way to name things so you know what they
are.
3. Multiply the value of orange & apple, then assign the result to a new
variable total.
When you feel comfortable using variables then go to the next lesson.
You have learned about variables & basic math operations in Ruby.
Example:
"bacon"
You need the quotes so you can tell the difference between strings &
variables.
A string is data.
food = "bacon"
This helps you reuse the string as many times as you want.
What Can You Do With Strings?
"bacon".size
# 5
"bacon".upcase
# "BACON"
There are methods that allow you to substitute all or part of the string.
Like gsub:
"bacon".gsub("acon", "inary")
# "binary"
"bacon".chars
You use strings whenever you want to print a message to the screen.
Like this:
Also when you read files, read input from the user (with the gets method),
or when you want to combine several pieces of information together.
Strings can contain numbers, but that doesn't mean you can treat them like
numbers.
"1" + "1"
Gives you:
"11"
If you want to convert a string with numbers into an actual integer value
you have to use the to_i method.
"1".to_i
Because integers are numbers, they must behave like numbers & allow for
mathematical operations.
Here's an example:
age = 20
name = "David"
Ruby replaces these #{name} & #{age} by their values, producing the
combined string.
How to Use Arrays
If you want to have many of the same thing then arrays are very useful.
Here's an example:
[1, 2, 3, 4, 5]
You can access every element by its position. We call that position an
index.
Example:
letters[0]
# 'a'
letters[1]
# 'b'
letters[2]
# 'c'
Important!
If you ask for an index that is bigger than the array size you'll get a nil
value.
# nil
And just like strings, arrays have a set of methods you can use to make
them do things.
For example:
letters.size
# 3
numbers = []
numbers << 1
numbers << 2
numbers << 3
numbers
# [1, 2, 3]
Both strings & arrays are very important building blocks for writing
your Ruby programs.
If you don't understand how these 2 work you won't be able to write even
the most basic projects you can think of.
If you don't know what irb is or how to open it you need to go back to
chapter 1 of this guide.
How to Use a Ruby Hash
You can get the value for a hash key like this:
ip_to_domain["rubyguides.com"]
# "185.14.187.159"
ip_to_domain["rubyguides.com"] = "8.8.8.8"
Create an array with the name of food with these values: "bacon",
"orange", "apple"
In this lesson you'll learn many different ways to write a Ruby loop.
You can go over a list of things, like an array or a hash, and work with each
individual element.
This loop requires you to have a collection of items, like an array, a range or
a hash to be able to use it.
Example:
numbers = [1, 3, 5, 7]
The way you tell the each method what do with every item is by using a
block...
...in this example the whole thing after each is a block: { |n| puts n }.
What happens is that each will use the block once for every element in the
array & pass every individual element into it, so this n is a variable that
changes.
Each Method With a Hash
If you want to use each with a hash you will need two parameters (one for
the key & another for the value).
Example:
There are cases where you want to use each but you need the index
number.
In the last example, with the each loop, we had access to this n variable so
we could print it.
Example:
Give it a try!
The key here is the little |i| thing, which by the way, can be any valid
variable name. It doesn't have to be an |i|. It could be |n| or |foo|, or
|bacon|...
If you are familiar with methods, this |n| is like a method parameter.
In other words, it's just a variable that becomes the current value for each
iteration of our times loop.
Range Looping
You may have noticed that when using the times method it starts counting
from 0.
You can use a range & the each method to have more control over the
starting & ending numbers.
Example:
And there are situations when only a while loop would make sense. For
example, if you don't know how many times you need to loop in advance.
n = 0
while n < 10
puts n
n += 1
end
The n variable
The n += 1
The variable n holds the value we are using for counting, the condition (n <
10) tells Ruby when to stop this loop (when the value of n is greater or equal
to 10), and the n += 1 advances the counter to make progress.
If you forget to increase the counter in your while loop you'll run into a
program that never ends.
An infinite loop.
Skipping Iterations
Let's say that you are going over an array of numbers & you want to skip
odd numbers.
10.times do |i|
next unless i.even?
The key here is the next keyword, which skips to the next loop iteration (the
next number in this case).
A better way to do this is to use other methods like step & select.
Example:
You can also break out of a loop early, before the condition is met, or before
you go over all the elements of the collection.
The following example stops when it finds a number higher than 10:
numbers = [1,2,4,9,12]
numbers.each do |n|
break if n > 10
puts n
end
Including the times method, the each method & the while keyword.
You have also learned how to control the loops by skipping iterations with
next & breaking out of loops with break.
Conditional Statements
Like these:
"If we don't have enough stock of this product then send an order to buy
more"
"If this customer has been with us for more than 3 years then send him
a thank you gift"
stock = 10
if stock > 1
puts "Sorry we are out of stock!"
end
This is what needs to be true for the code inside the condition to work.
"If the value of stock is less than 1 then print the 'out of stock' message,
otherwise do nothing."
Types Of Conditions
In the last example I'm using the "less than" symbol <, but there are other
symbols you can use for different meanings.
Here's a table:
Symbol Meaning
< Less than
> Greater than
== Equals
!= Not equals
>= Greater OR equal to
<= Less OR equal to
One equals sign = in Ruby means "assignment", make sure to use == when
you want to find out if two things are the same.
If you don't this right you won't get the expected results.
Ruby Unless Statement
But when you want to check for "not true" there is two things you can do.
if !condition
# ...
end
Or you can use unless, which is like if, but it checks for "not true":
unless condition
# ...
end
The If Else Statement
You can also say "if this is NOT true then do this other thing":
if stock < 1
puts "Sorry we are out of stock!"
else
puts "Thanks for your order!"
end
The else part is always optional, but it can help you write more advanced
logic.
You can take this one step further & use an elsif statement:
if stock < 1
puts "Sorry we are out of stock!"
elsif stock == 10
puts "You get a special discount!"
else
puts "Thanks for your order!"
end
"If stock is less than 1 print this message, else if stock equals 10
print this special message, otherwise if none of these are true
then print the thank you message."
How to Use Multiple Conditions
If you'd like to write compound conditions, where you are checking if two
things are true at the same time, then this section is for you.
This is saying:
"If the name is equal to 'David' and country is equal to 'UK' then do
something."
if age == 10 || age == 20
end
This means:
Notice how these two operators (&&, ||) allow you to combine conditions,
but they need to be proper conditions.
if age == 10 || 20
end
Just before we end this lesson & want to mention a few problems you may
run into & what to do about them.
When comparing two strings they must look exactly the same!
name = "David"
expected_name = "david"
if expected_name.downcase == name.downcase
puts "Name is correct!"
end
By making both strings downcase you can make sure they'll match if they
have the same content.
For example:
Another problem you may come across with related to arrays is "special
symbols".
These symbols are for things like new lines n & the tab key t.
The problem is when you try to compare two strings that look the same, but
they have one of these special symbols.
To see these special symbols you will need to use the p method:
name = gets
p name
Try this code, type something in, and you will notice that name contains the
newline character (which is not normally visible with puts).
name = gets.chomp
p name
If Construct in One Line
Like this:
if 2.even?
puts 123
end
I have another article where you can learn more about how this works &
learn about other useful Ruby operators.
Read that, then practice & review what you learned today.
Conditions allow you to take decisions in your code, this is what makes your
program "think".
You also learned how to use the if statement & the else statement to
handle different situations where you want to make decisions.
Finally, you learned about a few things to watch out for, like string "casing"
& special symbols.
If you studied (not just read once) the previous chapters of this tutorial now
you have all the components you need to build Ruby programs.
To review:
Variables
If statements
Loops
With these 4 things, plus Ruby built-in commands (we call these methods)
you have all the power of Ruby in your hands.
When you know what you want to do write a list of steps in plain
English.
Here's an example:
Let's say that I have a folder full of mp3 files & I want to print them sorted
by file size.
Now:
To turn these steps into code you'll need to get creative & use
everything you have learned about Ruby.
You can store temporary data in an array, string or hash to build this
solution.
Think like a car factory, every step the cars gets closer to completion.
Every step has one job.
Work "inside out". Figure out how to make something work for one case
then generalize with a loop.
If you are writing code directly in a file run your code often so you can
find errors early.
Most of the time the error message has information to help you fix
the problem.
There are two things you want to look for in an error message:
This tells you that the error started at the exception.rb file, on line 7.
This means you tried to use something with the name of bacon, but Ruby
can't find anything with that name.
It's possible that you made a typo, or maybe you forgot to create that
variable.
letters[5]
letters[5].foo
if letters[5]
letters[5].foo
end
If you find another error that you don't understand you can drop it into
Google & you'll find some hints on how to fix it.
Finding Ruby Methods
When converting your steps into code it's useful to know what you're
working with.
If you are starting with a string then string methods will be useful.
If you are starting with an array then look for an Array method that does
what you want.
You can find all the available methods using the Ruby documentation.
For example:
If I have a string like "a,b,c,d" & I want to break it down into an array of
characters without the commas.
A quick test in irb reveals that this is what we were looking for!
If you don't know what kind of object you are working with you can use the
class method.
Example:
"apple".class
# String
If you're working with a string, but you want to do something that only an
array can do, or you're working with an integer but you want to work with
the individual digits.
Method Conversion
Method Conversion
to_i String -> Integer
to_s Integer -> String
chars String -> Array (individual characters)
split String -> Array (split by spaces by default)
join Array -> String (join without spaces)
Both split & join take an optional parameter where you can specify the
separator character.
Example:
"a-b-c".split("-")
You may want to pull down data from a website & find images to download.
Ruby gems are small Ruby applications that you can add into your program
& they'll help you do something.
For example:
Nokogiri helps you read HTML code & extract information from it.
RSpec & Minitest help you write tests to check if your code is working
correctly.
You don't need the gems to do these things, but they can save you a lot of
work.
Object-Oriented Programming
But using OOP makes things easier if you're writing a non-trivial program.
Why?
Because OOP is all about how you design & organize your code.
For example, you may have a user class that knows the username & email
address.
class Book
end
This class does nothing, but you can create objects from it.
The class is the blueprint & the objects are the products.
Why?
Because this allows you to create many objects that are the same thing (like
a Book) but have different data (title, author, etc.)
How to Create Ruby Objects
Here's how:
book = Book.new
Like Array:
array = Array.new
But since these are built into Ruby we get special syntax to create them.
Example:
array = []
hash = {}
string = ""
For your own classes you have to use new to create objects.
Ruby Methods - How Classes Learn To Do
Things
Let's make our Book class smarter & teach it how to do something.
A method is a command that you can reuse multiple times & it's
associated with a specific class.
Here's an example:
class Book
def what_am_i
puts "I'm a book!"
end
end
When you call this method by its name it will print some text.
book = Book.new
book.what_am_i
Important!
Here's how:
class Book
def initialize(title, author)
@title = title
@author = author
end
end
Instance variables.
To store data that all the methods (in the same class) can use.
The last piece of the puzzle is how to access this data we prepared inside
initialize.
deep_dive.title
Instance variables are private by default, that's why we can't get the title
directly.
Like this:
class Book
attr_reader :title, :author
Now if I do:
deep_dive.author
# "Jesus Castello"
It works!
def author
@author
end
Because methods have access to instance variables they can return their
value.
attr_reader (read-only)
attr_writer (write-only)
When you use attrwriter or attraccessor you can change the value of
instance variables outside the class.
Example:
deep_dive.title = "Ruby"
Everything you have seen so far is about instances, objects created from
the class (using new).
Like this:
class Food
def self.cook
end
end
The self part before the method name makes this a class method.
Now:
Food.cook
Math.sqrt(25)
You don't need a Math object because Math doesn't store any data.
The methods in Math take one value & give you an answer.
That's the only way you'll develop this skill & improve your understanding!
Try this:
Add a meow method to the Cat class that prints "I'm a cat, gimme
food & pet me now!"
Congratulations!
There is a lot more to learn, but you put the initial work & planted the
seeds.
Now: