Sunteți pe pagina 1din 162

Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

1 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Ruby For Beginners


Ruby Monday Study Group (http://rubymonstas.org) curriculum for beginners

This book has been written after we have run 4 beginners groups at our Ruby Monstas
(http://rubymonstas.org) groups in Berlin, and it outlines the current state of our beginner groups
curriculum.

After completing this curriculum you’ll be able to read, understand, and write basic Ruby code
yourself:

You can use this knowledge to create small tools that might help you in your day-to-day work (such as
converting numbers, or extracting data from �les) that normally would cost a lot of manual work.
You’ll be able to jump into other tutorials, and have a much easier time understanding what they’re
talking about. And you can start working on our next curriculum which will walk you through the
basics of building an actual web application (http://webapps-for-beginners.rubymonstas.org).

If you’d like to print this book, or export it as a PDF try using this page, which is a single-page version
of the entire book.

You can �nd the source code of this book here (https://github.com/rubymonsters/ruby-for-beginners).

Preface
Read this book at your own pace, and do exercises at your own pace.

We recommend reading at least a page a day (ideally more), and taking some more time, at least once
a week, in addition to the weekly meeting on Mondays. It often helps to meet with others, have some
co�ee and cake, and hang out while reading some more of this book, or doing a few exercises
together.

We suggest that you read the book from beginning to end, and do exercises as you go. If you come
across chapters that you feel are too theoretical you can skip them for the time being and come back
to them later, if needed.

If you’d prefer to jump right in, you can also skip over the introductory chapters. Jump to the chapter
“Your tools”, and read the introductory chapters later. If you already feel familiar with your editor and
terminal, and know how to use ruby to execute a Ruby �le, then you can skip over the chapter “Your
tools”, too.

Take notes about whatever questions come up during the week, things that you don’t understand,
and everything else worth mentioning (for example, epiphanies you have, or things you found
interesting). Bring your notes to the study group so we can talk about them in the group.

Please help us improve this book for others: Whenever you �nd something unclear or missing then
please tell us. You can do this during the study group, email the mailing list, or ideally �le an issue
2 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

here (https://github.com/rubymonsters/learning_ruby/issues/new). (This also helps you get familiar with


GitHub, which we will use a lot later on.)

By using the name “Ada” in examples in this book we give credit to Ada Lovelace, the world’s �rst
computer programmer (http://en.wikipedia.org/wiki/Ada_Lovelace) :)

Resources
We also recommend looking at, reading, and working through other resources, as much as you can.
Every beginners book expresses things a little bit di�erently, in a di�erent order, and from a di�erent
angle.

Overview

Codecademy Ruby Glossary (http://www.codecademy.com/glossary/ruby)


Rails Beginner Cheat Sheet (http://www.pragtob.info/rails-beginner-cheatsheet/index.html) by Tobias
Pfei�er
Ruby Docs Cheat Sheet (http://overapi.com/ruby)
Ruby API documentation (http://ruby-doc.org/core-2.2.0)

Recommended reading

Ruby in 100 minutes (http://tutorials.jumpstartlab.com/projects/ruby_in_100_minutes.html) by


JumpstartLab
A Beginner’s Guide To Ruby (https://hackhands.com/beginners-guide-ruby) by Marc Gayle
Learn to Program (https://pine.fm/LearnToProgram/chap_00.html) by Chris Pine
Ruby for Webdesigners (http://rubyforwebdesigners.com) by Patrick J. Sparrow
The Poignant Guide (http://mislav.uniqpath.com/poignant-guide/book) by Why
Mr. Neighborly’s Humble Little Ruby Book (http://www.humblelittlerubybook.com) by Jeremy
McAnally
Beginning Ruby (http://www.amazon.com/books/dp/1590597664) by Peter Cooper
Programming Ruby (https://pragprog.com/book/ruby4/programming-ruby-1-9-2-0), “The pickaxe” by
Dave Thomas
Eloquent Ruby (http://www.amazon.com/Eloquent-Ruby-Addison-Wesley-Professional-Series
/dp/0321584104) by Russ Olsen

Online courses

Try Ruby (http://tryruby.org)


RubyMonk (http://rubymonk.com/learning/books/1)
Codecademy (http://www.codecademy.com)
Code School (http://www.codeschool.com)
Odin Project (http://www.theodinproject.com/ruby-programming)

Puzzles

Ruby Warrior (https://www.bloc.io/ruby-warrior) by Ryan Bates and Bloc.io

Role model stories


3 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

It Takes a Village to Make a Programmer (https://www.youtube.com/watch?v=FHNrw7aiKOE) by


Michele Guido
Rails Girls Berlin Success Stories (http://railsgirlsberlin.de/category/success-stories)

Resources for coaches

Tips for coaching a programming study group (http://coaching.rubymonstas.org)

Programming is creation
Things coming to life

Programming is creation. Whenever you run a program a little universe is created. Things come to life
and interact with each other, according to the rules that you, as their creator, de�ne.

Imagine you build an application like Twitter. Then, as a developer, in the programming language of
your choice, you would say things like “Let there be users! And let there be tweets!”, and once your
application starts these things will come into existence. Next you would go ahead and de�ne “Users
can create tweets, and they can follow each other”. And from now on, every time new users are
created in the little universe that is your application, these users will have the ability to tweet and
follow each other.

Learning to program
Brainwashing yourself

Learning to program means, fundamentally, two things: Learning a new language, and learning to
solve problems by way of using this language. This means writing code and describing your solution
to the problem.

When this text, the one that you are reading right now, was written, the author used the language
English trying to come up with an adequate solution to the problem “How can someone best start
learning to program?” Reading this text you also use the language English. If you think about what you
are doing right now, you will notice that you do not think about English as a language at all. Right?
Instead you use the language in order to �gure out what this author might be talking about, and what
that might mean to you.

Try to remember when you last walked up the stairs. Walking up the stairs is a pretty complex series
of movements, and it took you quite a while to properly learn it as a child. The exact order and
coordination of movements, bending your knees, ankles, while keeping your overall balance, is so
complex that we probably wouldn’t even be able to describe it properly. However, we have somehow
managed to learn this ability and we can now use it.

The point I am trying to make here is: When you last walked up the stairs you were thinking about all
sorts of things. Maybe you were on the phone with someone, searching for your keys in your pockets,
and thinking about looking for a nice introduction to programming online … maybe you did all of this
4 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

at the same time. Whatever it was, you did not think about how exactly to bend your knees and ankles
while trying to maintain your balance and get up to the next step.

Programming is very much the same. As programmers, while we program, we do not think about the
programming language, and how to use it. Instead we simply use it, and meanwhile think about very
di�erent things, such as the problem we are trying to solve, how we can make things easier for fellow
programmers, how to best suit the needs of our users, or customers, and so on.

When you start learning to program you will �rst learn about the basic concepts of the programming
language. And you sometimes may feel slightly overwhelmed, and wonder how programmers might
be able to remember all this stu�. The trick is: they don’t, consciously. Instead they have assimilated
these concepts so much that they are able to simply use them, without consciously remembering or
thinking about them. Just like you use English, or your ability to walk up the stairs.

That’s why learning a programming language, just like learning any other language, or skill, is a lot
about repetition: You basically brainwash yourself into being able to form meaningful “sentences”
(code) without having to think about the concepts that you are using.

Over time, while you repeat basic concepts of Ruby over and over again (by way of doing exercises
and writing code) you will notice that things become very natural, and this probably will happen much
quicker than you think.

At �rst, you will not understand anything. It’ll be weird, just like with learning any human language.
You will struggle with words, and not know what symbols are what, and it’ll all be very confusing. Then
one day BANG your brain will snap and you will suddenly “get it.” If you keep doing the exercises and
keep trying to understand them, you will get it. from the great book Learn Ruby The Hard Way
(http://learnrubythehardway.org/book/intro.html) by Zed Shaw.

Learning modes
People are di�erent

Di�erent people learn things in di�erent ways.

Some like to listen to lectures, or read books that thoroughly explain concepts before they then start
exercising, and experiment with what they just learned. Others like to get their hands dirty, and play
with code until it does what they want.

Some want to fully understand what a certain line of code does, and why. Others don’t care that much
about the details, and want their code to produce the right things instead. They might memorize what
worked, and understand things more fully later.

Some understand concepts in logical ways, and go precisely by their de�nitions. Others understand
things better by coming up with good analogies and metaphors. And yet others tend to simply
memorize things and how they get used.

Therefore there is no one true path or one-size-�ts-all approach to learning programming. Try
di�erent things, and pay attention to what works well for you, what is the most fun to you, and keeps

5 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

you motivated.

If you �nd it hard to keep motivated working through a certain online tutorial, or if you have a hard
time fully understanding what an exercise is about, then try to pick a di�erent approach, or talk to
your study group.

Consider meeting with others during the week, have some co�ee and cake and hang out, read some
more of this book, or do a few exercises together.

Also, consider joining local programming events, like meetups, hackdays, or a conference once in a
while. That gives you a broader perspective, even if you might not be able to fully understand
everything all the time. Meeting with others and hearing about their experiences can also be a good
source for inspiration and motivation.

If you can’t put a lot of time into learning programming, then consider spending at least a few minutes
on it every day. For example, every morning, before you leave the house, take 10 minutes to read a
page in a programming book, review an exercise, or read some code. Or spend some time with it on
the train on your way home from work later. This will keep your subconscious mind busy with
programming concepts, and help you pick things up more easily later.

Don’t believe everything we say


While you are learning to program you’ll talk to seasoned developers, ask questions, and listen to
their advice, tips, and experiences.

That’s great! We recommend you listen closely, try to understand, and ask more questions.

However…

Always try to put things into perspective. Whatever you hear, try to understand, compare with other
opinions, and judge for yourself.

As in any other �eld, developers, as much as any other person, will always give answers based on
their own perspective, based on their own experience, and based on what they think is a helpful
answer to you. Now, being a great Ruby developer (“knowing your stu�”) and being a great Ruby
coach (“giving the right advice”) are not the same thing.

Developers who have never coached, or are new at coaching, tend to, for example, overload you with
information. They know all this stu�, and, as said before, they aren’t even fully aware of it. They just
use the language, and all these features.

Now, when asked to explain things, and may suddenly remember: “Oh, right, and then there’s also
this other language feature, and that one, and another one, and …!” They may be excited to explain all
the things at once, without realizing that, at this particular point, you actually don’t need to know them
all at once.

Also, they might present a conclusion, and omit the learning process. In programming, as much as in
any other �eld, there’s rarely any silver bullet. There are always alternative solutions, with di�erent
advantages and downsides. Often it’s hard to fully understand them unless one tries a particular
6 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

solution and sticks with it for a while.

On top of this, whatever is considered a “good” solution by the community at any point of time, is
always the conclusion of a decades-long evolutionary learning process. Often it makes sense to start
practicing with an older and simpler solution that worked well enough a couple of years ago, and
experience some of the problems it caused, and only then try using the latest, more modern solution.

Developers often tend to be excited about their current preferences, and things they’ve learned just
recently, and will happily explain at length why one solution works better for them than another.
Often you can learn a lot from listening to these explanations. However, keep in mind that this doesn’t
necessarily mean a tool that’s great for an experienced programmer is also a tool that’s great for
learning to program.

On top of all this, there’s also the problem that the tools we use, over time, become more and more
optimized for advanced users. New features are being added that make our day-to-day work easier,
and over the years, up-to-date documentation and tutorials will focus on these features.

While that’s great for advanced users, it’s sometimes bad for beginners, as you now not only need to
understand the basic concept, you also need to understand this additional, more abstract feature that
sits on top of it.

A good coach will try and adjust to these things, but doing so also is a skill that needs to be learned.
Try to give feedback, and help your coaches improve.

Of course, everything said above also applies to ourselves :)

Here are a few examples of decisions we made for our study groups. Don’t worry if you don’t
understand what we’re talking about at this point. You’ll fully understand them once we get there
during study group.

7 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

We use the old syntax for hashes in beginners groups: When you �rst learn what a hash is, and
how it is used, this is quite a bit of information to process. The new hash syntax puts an extra
burden on you, and raises extra questions that just aren’t required to be answered in order to
understand what a hash is, how it can be used, and why it is useful. We do mention the new
syntax, and explain why we do not use it.

We purposefully ignore tons of language features, such as for and while loops, lambdas, splats,
class level methods, class variables, and so on. Our goal is to get to the point where you can write
a simple Sinatra application while fully understanding everything you use in terms of Ruby
language features. We found this is the point where it starts getting more and more exciting for
most students: You can now build your own web applications, and understand what you’re doing.
For this, many language features simply aren’t required.

We use the test framework that is integrated into Ruby on Rails, rather than RSpec, another, more
modern framework that is preferred by many (but not all) Ruby programmers. Why? It is easier to
understand: methods are just methods, not method calls that generate other methods that
magically do things. You don’t need to learn a lot in order to start writing your �rst test, and there
is no additional setup required. Later on, once you’ve written a good bunch of tests, it is a great
idea to then learn RSpec, and try that one for a while.

One example of technology improving, adding features optimized for more advanced users, and
thus making it harder to understand for newcomers, is the aforementioned new hash syntax.
Other examples are: Rails’ resources macro in routes (it is much easier to understand the whole
concept if you type out these 7 routes yourself), and Rails’ migrations (they’ve gone, for good
reasons, from being numbered to being timestamped, making the naming choice migrate:up and
migrate:down harder to understand; and they’ve introduced the method change , replacing the
methods up and down ).

Formatting your code


Keeping things pretty

By “formatting code” we refer to the way code is indented, or not, where and how whitespace is being
used in order to separate things visually, or not, etc.

For example, even though this code won’t mean a lot to you at this point (it will, in a few chapters), it is
formatted well:

def widths(row)

row.map do |cell|

cell.width

end

end

Even without understanding what these few lines of code do at all, from just looking at it one can
8 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

recognize a certain structure: things are somehow nested, and stu� that sits on the same horizontal
indentation relates to each other visually.

On the other hand the following code also is perfectly valid Ruby code, in the sense that Ruby will
happily run it, and it does exactly the same. However, it is not formatted very well at all (in fact it’s
quite a mess, isn’t it?):

def widths ( row

row.map do | cell| cell.width

end

end

This does the same, technically: Ruby will run it. But it does not look and read the same, simply
because of the way it is formatted.

Pattern recognition
When you talk to developers about your code you will probably notice very quickly that we are all
obsessed about how exactly we’d like code to be formatted.

There’s a good reason for that, and you should try hard to learn how to use your editor in order to
format your code properly, so over time, you can become obsessed, too :)

The reason for this obsession is pattern recognition: The ability of our brain to help us recognize
things subconsciously, from just glancing over them.

Imagine you are driving a car, and there’s a kid playing with a ball on the sidewalk. Even if you only see
the kid from the corner of your eye your brain will immediately process this information and even
assign a meaning to it. You’ll start paying attention, and maybe lower your speed immediately.

Often when you search for something online, and look at a couple of websites, your brain will help
you recognize things that you are looking for without consciously thinking about the structure of the
site.

In the same way, as a programmer, when you look at code, you will immediately recognize some of its
structure, and thereby understand it, without reading it thoroughly. This allows you to to grasp the
overall picture of what you’re looking at, and quickly �nd something that you’re looking for, in order to
then read this particular part of the code more carefully.

As you can imagine, in order for this kind of pattern recognition to kick in, code needs to be formatted
consistently and carefully.

Another aspect of this is that looking at “badly” formatted code causes discomfort to an extent that it
is described as causing physical pain. While this might seem like an exaggeration, there’s something
important to it.

Because of how pattern recognition works, as a programmer, whenever there’s a small issue with the
9 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

formatting of some code, you will immediately notice it, and distract yourself from other thoughts.
You’ll need to re-focus on what you were trying to accomplish, and whenever you come back to the
code it will distract you again.

That’s why developers often feel the urge to �x even small formatting mistakes immediately. People
might outright refuse to talk about your actual code, and any questions that you have, before you’ve
added this one extra space here, and indented that other single line there.

(One certain aspect of this has been even baked right into the language Ruby. For example, by
de�nition, class names must start with an uppercase letter. On top of this, the Ruby community has
agreed on conventions for how to write other names. We’ll get to this once we talk about variables
and classes more.)

Reading error messages


Your new best friends

As programmers we want to build things that work. When we do exercises we want to �gure out the
solution to the given problem. Seeing error messages therefore has a negative connotation to it: we
haven’t managed to get it right! Right?

Well, yes. But also, no. Errors can also indicate progress. Often error messages indicate that we’ve
done the right �rst step, and now have to �gure out the right next step.

Whenever you �nd an error message printed on your terminal, don’t fret. Instead, appreciate it. Read
it carefully. Ruby is trying to give you a hand and help. Normally an error message tells you exactly
what went wrong in your code, and where. Once you’ve understood what has happened look at your
code and try to understand why it happened, and how you might �x it.

Often, when you �x one thing, you’ll get a di�erent error message. That’s progress. Rinse and repeat
until your code does what you want.

For a beginner, Ruby error messages can sometimes be hard to read. There are certain conventions
used, e.g. for indicating there’s an instance of a certain class involved. Backtraces might be hard to
read and might look frightening. But all they do is tell you the exact path of execution Ruby took until
it ended up raising an error.

If you do not understand an error message and you have the opportunity to ask someone else, then
do so. You’ll get better and better at reading error messages over time. And you’ll become friends with
them.

Using Google
Someone else has already had that question

Whenever you have a question, and you’re not sure where to start looking for an answer, simply go

10 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

ahead and ask Google. Some other person most probably has had the same question before, and
often times you will �nd a helpful blog post, tutorial, documentation, or answer on community sites
like Stack Over�ow.

Finding the right terms to type into Google might take some time. Experiment with this. If one
question does not yield a helpful result on the �rst page, try to rephrase your question. You’ll get
better and better at this over time.

Always include the keyword “ruby” though, so you don’t get answers for other programming
languages.

E.g. if you are wondering if there is a method that gets you all the keys from a hash, then google for
“ruby hash get keys”. If you are wondering if there’s a method to align strings so they all have a certain
length, then google for “ruby string align”.

Google results that link to the Ruby documentation on ruby-doc.org are often good ones to look at,
but these pages also often are very long. Look at the summary of the page on Google, and the
highlighted terms, then go to the page and use your browser’s search feature to �nd them on the
page.

Also, results on Stack Over�ow are often very worthwhile to read. This is a programming community
site where people with all kinds of experience levels post questions, which then will be answered by
others. People can rank answers, and the best ranked answer appears at the top. Often it is worth
skimming through most of the answers, as sometimes the question asked is just slightly di�erent
from yours, but someone might still suggest a solution that might be similar to the one you are
looking for.

Your tools
When you start learning programming in Ruby you’ll need three tools: A text editor, a terminal, and a
Ruby runtime.

As a programmer you’ll spend tons of time working with your text editor and terminal (or “in” them, as
we say). It makes sense for you to learn how to use these tools, and how to customize them so they �t
your taste.

There are also text editors that can be integrated into a terminal window. This means you don’t have
to switch between applications. There are also online services that integrate all of this as a web
application, with a nice interface in your browser.

Feel free to try all these things out, and play with them as much as you like. However, for our study
groups, we have found that using the simplest tools possible, at least for a while, works best: It
reduces the amount of things people need to learn in the beginning, and everyone learns the same
few basic things that are required to run a Ruby program in this environment.

Text Editor
11 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

For our study groups we recommend using Sublime Text (http://www.sublimetext.com) as a text editor,
which you can download and run on Mac OSX, Ubuntu, or Windows. This is an editor that has been
speci�cally designed for writing code, comes with a lot of great tools, and can be easily customized.

Other text editors that might be worth looking at are Atom, Textmate 2, and, if you like to use some of
the powerful oldschool tools from the early times of Unix, VIM and Emacs. These are all great editors
to use.

Whatever editor you use, you want it to insert 2 spaces when you hit the “tab” key, i.e. when you want
to indent your code. Make sure your editor is con�gured to do this.

For Sublime Text you can do the following: In the menu item “Sublime Text” go to “Preferences” and
select “Settings - User”. This opens up a con�guration �le that you can edit just like any other �le.
Make sure it looks like this:

"tab_size": 2,

"translate_tabs_to_spaces": true

Also, we recommend enabling auto-saving your �les. This will automatically save your changes when
you switch to another application (like your terminal), and protect you from the mistake of forgetting
to save:

"tab_size": 2,

"translate_tabs_to_spaces": true,

"save_on_focus_lost": true

Whenever you open a new �le, make sure to save it with a �lename that ends with .rb �rst. This will
tell the editor that you want this to be a Ruby �le. Your editor will start highlighting your code as Ruby
code, and enable other Ruby speci�c editor features. Alternatively, select “Ruby” in the extensions
menu at the bottom right.

Some keyboard shortcuts that are extremely useful to know are:

In order to indent or unindent a single, or multiple lines of code, select them and hit tab or
shift-tab respectively.
In order to comment single, or multiple lines of code, select them, and hit cmd-/ on Mac OSX, or
ctrl-/ on Linux/Windows.
Cut out code with cmd-x , copy code with cmd-c , and paste it with cmd-v on Mac OSX, on
Linux/Windows use the ctrl key instead.

12 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Terminal
Every operating system comes with some kind of terminal application built in, and they’ll be �ne to
use for us.

A terminal is an application that doesn’t do much more but provide a window to run another
program, called a “shell”. A shell is a text-based program, so it does not have a window, and thus
needs the terminal to be run on your graphical user interface.

A shell is an interactive program that waits for you to type a command and hit enter (or “return”). It
will then run the command, display any output, and then, again, sit and wait for you to type the next
command.

This is how working with computers was done in early times before there was the idea of a graphical
user interface with clickable icons, windows, and a mouse as an input device. Instead, everything was
done by typing commands.

While this might take a little while for you to get used to, you’ll discover why many programmers feel
that working with the shell helps them be so much more productive and get simple things done so
much quicker than using a mouse and a graphical interface.

The default settings for most terminal applications that come built in to operating systems are quite
poor, unfortunately. For example the Terminal.app on Mac OSX opens a tiny little mini window with a
very small font. You want to make the window much (much!) bigger, and �nd the settings to pick a
bigger font size. As a programmer, the terminal (along with your editor) is your new home. You want
to be as comfortable reading and writing in your terminal as in any other application.

In case you are using Microsoft Windows it is highly recommended to use any kind of unix based
terminal. One option is Git-Bash (https://gitforwindows.org/ (https://gitforwindows.org/)). However, as
Ruby and Microsoft Windows are not best friends, it is even better to install the Windows Subsystem
for Linux which is available here for Windows 10: https://docs.microsoft.com/en-us/windows
/wsl/install-win10 (https://docs.microsoft.com/en-us/windows/wsl/install-win10). With this option you can
install everything you need for your Ruby development under Ubuntu and use Bash as your main
shell.

All commands in the following texts are unix commands and will not work in a Microsoft Windows
terminal.

Once you have started the terminal program you will see your shell’s prompt, and can start typing
commands. You’ll want to learn at least the command cd which allows you to navigate to a particular
directory (where you have stored your code), and the command ls which lists the contents of a
directory.

Also learn how to use the command line completion using tab : For example, type cd , space, and the
�rst two or so letters of the directory you want to navigate to, then hit tab . The shell will complete the
rest of the directory name for you. If nothing happens, then there are multiple directory names
starting with the same few letters. In this case hit tab twice, quickly, and your shell will display a list of
choices. Type the next letter and hit tab again.
13 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Ruby runtime
The last tool you need is a Ruby runtime. This is a program that can execute Ruby code, and it is a
program that can be run in your shell (much like cd and ls ).

If you have some code in a �le with the name hello.rb , and you have navigated to the directory
where the �le is saved, then you can type the following and hit enter, in order to execute the code:

ruby hello.rb

This will tell the ruby runtime to interpret the contents of the �le hello.rb as Ruby code, and
execute it.

One can also use this program to do other things. You probably won’t need these a lot, but we think
it’s good to know. You can try these by typing these commands in your terminal.

E.g. you can print out the version of the program:

ruby --version

Or execute Ruby code without storing it to a �le:

ruby -e 'puts 123'

Programming work�ow
In order to do programming excercises on your computer, play around with things you learned, and
write actual, useful programs you want to learn the following work�ow:

Write some code in your text editor.


Save the code to a �le in a particular directory. The �lename should end with .rb .
Open your terminal.
Navigate to that directory using cd .
Execute the �le using ruby .
Switch back and forth between the text editor and terminal, so you can make small changes in
your code, and then run it through ruby to see what it does.

In order to switch back and forth between apps quickly you can use the keyboard shortcut cmd-tab
on Mac OSX, and alt-tab on Ubuntu and Windows.

14 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

In your shell you can use the cursor up key to go through your last used commands: you don’t have
to type ruby hello.rb again. Just hit cursor up and then enter to run it again.

Interactive Ruby
One other tool that is worth mentioning, and that comes with your Ruby runtime, is irb . You can
start it by typing irb in your shell and hitting enter.

Its name is short for “Interactive Ruby Shell”, and yes, it is another kind of shell: Just like the shell
running in your terminal irb is also a program that interactively waits for you to type something, and
hit enter. However, since this is a Ruby shell, it will expect that you type Ruby code instead of system
commands.

IRB is pretty handy for quickly trying something out, and it is a great tool for exploring the language
Ruby, and things that come built in.

For example:

$ irb

> puts "Hello world!"

Hello world!

=> nil

>

The �rst line starts the IRB program. Notice how the “prompt” indicator changes. The prompt will look
a little di�erent depending on your system and shell con�guration, but often $ is used to indicate
that this is a system shell prompt, while > is used by IRB to indicate that this is an interactive Ruby
shell.

The second line is a piece of Ruby code. When you type this line and hit enter then Ruby will execute
the code, and print out the text “Hello world!”.

It will then also print out the return value for this statement, which in this case is nil . This is
something that you can simply ignore for the time being.

On the last line you see IRB again waiting for input with a prompt.

You can exit the IRB session, and get back to your system shell, by typing exit and hitting enter. Or
you can also just hit ctrl-d , which does the same thing.

Our Roadmap
Ok, let’s get started.

15 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Here’s a rough overview of the road that lies in front of us, and topics that we’ll cover.

This curriculumn is built on top of two main ideas:

We introduce one concept after another. Doing so we try to make sure not to assume any
knowledge but things that already were explained.
We get you to a point where you can create your own classes, objects, and methods as quickly as
possible: We found that’s the point where it starts to be most fun for most people.

Of course you don’t have to follow exactly this path. For example, if you’re curious, after we’ve
introduced the most basic built-in types of things in Ruby, numbers and Strings (text), you might �nd
there’s another chapter about more such types. Feel free to skip ahead, and read it. Just be aware that
you might �nd this chapter assume a couple more things.

So, here’s our roadmap:

1. Object Oriented Programming

We’ll look at the main idea (concept, paradigm) behind programming in Ruby from a little bit of a
philosophical perspective. We do this to set a little bit of a context for the terms object, class, and
method which will be used quite frequently from then on.

2. Variables

In order to do things with objects, and form readable sentences (code) we need to be able to assign
names to them.

This chapter explains variables in Ruby.

3. Built-In Data Types

Ruby comes with lots of batteries included. Things that are built-in, and ready for you to be used
when you open an empty Ruby �le, or IRB.

We’ll look the two most basic, and most widely used ones:

Numbers, and Strings (text). These will be good enough for us to introduce other concepts without
spending too much time on talking about all the other things that Ruby has built-in (we’ll look at the
most important ones later).

We’ll quickly mention 3 primitive things that are widely used in Ruby: true , false , and nil , so you’ve
already heard of them when we come across them later.

Then we discuss Arrays and Hashes, which are data structures. I.e. these are things that you can use
to store other things. They’re pretty powerful, and widely used.

Symbols are quite an odd beast, and you normally wouldn’t even need to know them in order to write
your own, working code. However, they’re very widely used and many (many!) examples out there use
them. So we introduce them brie�y, too.

4. Objects, Classes, Methods


16 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This chapter discusses how objects and classes relate to each other, how methods can be called on
objects, and explores a number of di�erent methods. It also has a quick look to see what’s up with
that magic, so-called top-level object in Ruby.

5. Writing Methods

While variables give names to things, methods give names to behaviour. Methods are like the swiss-
army knife of programming. We’ll have a look at the anatomy of a method, and learn how we can
de�ne our own ones.

6. Writing Classes

With this knowledge at hand we can now go ahead and de�ne our �rst class (kind of thing) ourselves:
We’ll de�ne the class Person , create some “people” (objects), and let them interact. We’ll learn how to
make our objects “know” things, and how to give them “behaviour”.

7. Blocks

Blocks are a super powerful feature in Ruby. We love them, and use them everywhere. Many built-in
methods use them, too. So it’s good to introduce them now.

Blocks are like methods that don’t have a name, and they are passed when calling actual methods.
We’ll discuss why this is cool, and how it works.

8. Conditionals, Truthiness, and Nothing

Sometimes you want to run some part of your code only if a certain condition applies (e.g. you only
want to allow users to login if the supplied password is correct).

Conditionals allow you to do that. Ruby comes with some pretty cool features included, and we’ll
quickly look at them.

9. Operators

There are lots of di�erent operators built into Ruby, and at this point you’ve already used a number of
them (such as the arithmetical operator + , and the assignment operator = ).

We’ll look at a few more, and also reveal that operators, in fact, are … methods in disguise!

Bonus and advanced topics

This concludes the core of our “Ruby For Beginners” curriculum. With this knowledge you’ll have all
the tools you need in order to play with things, read (most of) other people’s code, and write your own
useful things.

There are a couple bonus chapters that you might want to skim through. Some of these are still
waiting to �nd their place somewhere else in the book. Some will probably be marked as optional.

Also there are some extra chapters about advanced topics, some of which are relevant to the more
advanced exercises, and for the next curriculum about building your own web applications
(http://webapps-for-beginners.rubymonstas.org/).
17 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Object-oriented programming
Classes and objects

Ruby is, like many other popular languages, an object-oriented programming language. Other object-
oriented languages that you might have heard of are C++, Java, Python, PHP, and Javascript. At some
point in the 1990s this paradigm started to become more and more popular and nowadays it is the
most prevalent one.

One reason for this is that object-oriented programming very much �ts the way we perceive and think
about the world, at least in the occidental culture. Our way of thinking was, historically, very much
in�uenced by Plato, and philosophers who followed him:

We somehow tend to think about the world as if there are abstract “ideas” (or concepts) and concrete
“things”, which are entities of the ideas, or implementations of the concepts. So, “ideas” are like
blueprints for “things”.

For example there’s the idea of a human being, and then there are actual human beings: you, and me.
Our idea of a human being includes the ability to, for example, remember our own name, and tell it to
others when asked. We know that we can ask people for their name, and they’ll know it.

Now, object-oriented programming languages allow you to describe things exactly this way: In object-
oriented programming languages “ideas” are called classes. And actual “things” are called objects.

As a programmer you would de�ne classes, like a class “User” and a class “Tweet”, and then create
actual instances of these classes: an actual concrete user with a name, email address, a password and
actual tweets. You would also de�ne that users have the ability to remember their own name, and the
ability to tell it to others when asked.

 Classes are like ideas, objects are concrete things, manifestations of their ideas.

Every object-oriented programming language comes with some “ideas”, that is, classes, already baked
in, and so does Ruby. For example Ruby has classes for numbers, strings (text), and other useful
things. You therefore can, without any further e�ort, do number calculations, or text transformations.

In your �rst excercises you will do just that. Later on you will learn to de�ne your own “ideas” as
classes, and then use them by the way of creating actual instances or objects, from these classes, and
then make them interact with each other and do interesting stu�.

By the way, here is a quote from a book titled The Early History Of Smalltalk (http://worrydream.com
/EarlyHistoryOfSmalltalk/) from 1993. It has been written by Alan C. Kay, one of the designers of
Smalltalk (https://en.wikipedia.org/wiki/Smalltalk), which was created in the 1970s, and can be considered
the �rst fully object oriented programming language. We think it’s pretty interesting to read.

“[Smalltalk’s] way of making objects is quite Platonic in that some of them act as […] Ideas from
which manifestations can be created. That the Ideas are themselves manifestations (of the Idea-
Idea) and that the Idea-Idea is a-kind-of Manifestation-Idea — which is a-kind-of itself, so that the
18 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

system is completely self-describing — would have been appreciated by Plato as an extremely


practical joke.” — Alan C. Kay

Anyhow, you can take away from all of this that those universes that we create when we write
programs will be populated by objects (“things”), and their characteristics are de�ned by classes
(“types of things”, or “ideas”).

This will start to make a lot more sense to you once you write your own classes.

 There is, today, some debate about the paradigm of object-oriented programming, and
whether we should move on to another one, called “functional programming”. You might
hear about this if you talk to developers. Some functional languages are Haskell, Go, and
Clojure, and they have recently started gaining some traction. Don’t let yourself be
distracted by this too much, unless you really want to. Ruby is a very good language to start
learning programming for lots of reasons.

Variables
Naming things

In order to refer to the “things” (objects) that our program deals with we want to assign names to
them.

Every practical programming language has a feature to do this, called variables. This is basically the
same concept that you might know from math, although in Ruby there are di�erent kinds of variables
(you will get to know another one in a couple chapters).

We’ll discuss this concept quickly because you already need to know it in the next chapter, and the
respective exercises.

If some of this seems rather abstract to you, don’t fret. It will become very practical, and you won’t
even think a lot about it any more, as soon as you actually work with variables while learning other
things.

Alright. Let’s jump right in:

In Ruby you can assign a name to something (an object) by using the so called assignment operator
= . Like so:

number = 1

This will assign the name number to the “thing” (object) that is the number 1 . From now on we can
refer to this object by using the name number . For example the following code would output the
number 1 :

19 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

 A name on the left side of the assignment operator = is assigned to the object on the right
side.

number = 1

puts number

One important thing to note here is that a variable is not a “thing” an object by itself. Instead it’s just a
name for an actual object. In our example the number 1 is an object, while number is a name for it
because we’ve assigned it.

 A variable itself is not a “thing”. It’s just a name for a thing (an object).

You can think of it like a post-it note with the name number written on it, and stuck on the actual thing,
which is an object (in this case, a number).

Imagine you were in the middle of learning some Spanish, and sticked post-its onto things in your
apartment: the name nevara onto the refrigerator, cama onto your bed, and puerta del baño onto the
bathroom door.

Now, whenever you use one of these terms, as in abrir la nevera (open the refrigerator) in order to
learn the language and rehearse vocabulary, you’ll obviously refer to the object, and open its actual,
physical door.

That’s pretty much how variable assignment works in Ruby. There’s a “thing”, the object on the right
side of the assignment operator = , and the name on the left side is being assigned to it.

Whenever we use a variable name that has been de�ned before we refer to the actual object that it
has been assigned to. E.g. on the second line of the code example above number refers to the actual
object, the number 1 that it has been assigned to on the �rst line. Therefore puts number outputs the
number.

 You can pick whatever variable names you want, they’re just names, like post-it notes stuck
onto actual objects.

Since names are just names, the following examples would do exactly the same:

20 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

a = 1

puts a

large_number = 1

puts large_number

apples = 1

puts apples

However, also note that it makes sense to try and pick names that reveal your intention. The chapter
Using the right words at the end of this book will talk more about this. Feel free to jump ahead if you
are curious. In short, the �rst example using a as a name would be frowned upon because it’s
wasting the opportunity to use a meaningful name. The second and third examples are just trying to
be stupid, and pick names that don’t match the “thing” (the object, number 1 ) at all.

There are a two more things about variable assignments that we’d like to point out before we move
on.

Reusing variable names


It is also important to keep in mind that a name is unique, in the sense that the same name can only
be assigned to one value (object) at a time.

In other words, if you assign di�erent values to the same variable, then assignments that happen later
will simply overwrite previous ones. Like so:

number = 4

number = number * 3

puts number + 2

This, again, would output 14 .

 Variable names can be re-used, and re-assigned.

The �rst line assigns the name number to the number 4 . The second line re-assigns it to another
object.

Getting back to our post-its metaphor … this would stick a post-it with the name number on one thing,
and then later take it o� of it, and stick it on something else.

Let’s look at it under the microscope:


21 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

On the �rst line Ruby creates the number (object) 4 .


It then assigns the name number to it (sticks a post-it onto it).
On the second line, Ruby �rst looks at the stu� on the right side, and evaluates the expression
number * 3 . Doing so it will create the number (object) 3 and multiply it with the object that
currently has the name number , which is 4 . This operation results in a new number (object) 12 .
Now Ruby is �nally ready to stick the name number on the result 12 . I.e. from now on the name
number refers to a di�erent object, which is 12 .
On the third line Ruby will, again, �rst look at the expression number + 2 on the right. It creates
the object 2 and adds it to the object that currently has the name number . This results in a new
number (object) 14 .
Finally Ruby passes this object 14 to puts , which outputs it to the screen.

Of course, you would probably never actually write this exact code in practice since you can simply do
all this in just one line instead: puts 4 * 3 + 2 .

However, sometimes you’ll �nd or write code that assigns an initial value to a variable, and then keeps
working on it for a few more lines. This sometimes is useful to break up long lines, and make code
more readable.

 Using variable names can be useful to break up long lines and make code more expressive
and readable.

Also, Ruby has di�erent kinds of variables.

The kind of variable that we’ve introduced so far is called a local variable, and it’s the one used most
often. You will learn about another type of variables later when we talk about classes and objects.

 On formatting: Note that there are spaces around the assignment operator `=` as well as
the arithmetical operators `+` and `*`.

Things on the right go �rst


One last thing that is worth mentioning about variables:

Just as in tra�c (well, at least in most parts of the world (https://en.wikipedia.org/wiki/Right-_and_left-


hand_tra�c)), things on the right side go �rst :)

For a variable assignment, in order to assign the thing on the right side to the name on the left side,
Ruby �rst needs to �gure out the thing on the right. As you will see later the same is true for many
other expressions in Ruby.

In our example above it will �rst create the object that is the number 1 , and then assign it to the
name number . The following example makes that more clear:

22 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

number = 2 + 3 * 4

puts number

When Ruby looks at the �rst line number = 2 + 3 * 4 it notices that this is using the assignment
operator = . Therefor, before it can assign the name number to the “thing” (object) on the right … it
�rst needs to know what that thing is.

So, before she does anything else, Ruby will �rst look at the expression 2 + 3 * 4 , which will result in
the number (object) 14 . She will then assign the name number to this object (i.e. evaluate the
assignment operator = ).

You can imagine that in this moment, when Ruby starts evaluating the assignment = the code
temporarily looks like this: number = 14 (because the calculation has returned the number 14 ).

Does this make sense?

Again, on the second line Ruby will then pass the thing with the name number (which is 14 ) to puts ,
which will output it to the screen.

 Ruby evaluates the expression on the right �rst.

Built-In Data Types


As mentioned before, Ruby comes with lots of things already baked in, and provides you with tons of
tools to use and hit the road running.

We’ll look at some of the most common data types in Ruby. Data types are types of “things” that are
mainly used to represent data, such as numbers, text, and other values.

This is basically the “stu�” that you, as a Ruby programmers will work with, when we work with actual
data, that is interesting to you, or your users in one way or the other.

We will discusss the following data types:

Numbers
Strings (texts)
True, False, and Nil
Symbols
Arrays
Hashes

These “kinds of things” (objects) cover like 98% of all built-in data types that you’ll be using on a day to
day basis, i.e. these are being used all over the place. There are more data types, but those are rather
exotic, and used much less often.

23 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Numbers and Strings (which is just a strange name for “texts”) are some of the most basic “things”
that you deal with in Ruby on a regular basis. The are also just enough lego bricks for us to dive into
more interesting topics, such as how objects, classes, and methods relate to each other, and how you
can create your own ones.

Before we do so we will also brie�y mention the “things” true , false , and nil , just because these
are things that we’ll come across along the way anyway.

Symbols also are very commonly used, but quite an odd concept. You normally wouldn’t need to
understand Symbols in order to write your own code. We’ll still cover them brie�y, and use them once
in a while, just in case you �nd them elsewhere.

Arrays and Hashes are “things” (objects) that are used to store other things, and they’re super useful,
and widely used.

Numbers
Numbers are simply numbers.

You can create one by writing it: 123 is Ruby code and it represents the number one-hundred-twenty-
three.

Negative numbers are created by prepending a minus - : This is the number minus-ninety-nine: -99 .

And of course there are decimal numbers, too. Again, you create one by writing it: 12.34 .

You can also use an underscore to separate thousands places: E.g. 1_234.56 is the number one-
thousand-two-hundred-thirty-four-point-�ve-six. However, this is optional. This is the exact same
number in Ruby: 1234.56 .

 A number is de�ned by a series of digits, using a dot as a decimal mark, and optinally an
underscore as a thousands separator.

Note that di�erent countries use di�erent punctuation for decimal and thousands separators. Ruby is
using the same notation used in the USA, which happens to be the exact opposite of what’s used in
Germany.

Kinds of numbers
Under the hood, for reasons that are mostly technical, there are actually di�erent kinds of numbers:

For example there are integer numbers (those without a fraction, i.e. a dot and decimal places), and
depending on their size there are two kinds of them. For �oating point numbers there are even more.
Unless you are super curious, you can perfectly ignore all of that for now, and just think of numbers
as numbers.

However, when you do calculations with numbers, keep in mind that integer numbers (“integers”) and

24 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

decimal point numbers (�oating point numbers, aka “�oats”) are di�erent.

If you do a calculation that uses integer number you’ll always get an integer back:

$ irb

> 1 + 2

=> 3

However, if any of the numbers involved is a �oat, then you’ll get a �oat back:

$ irb

> 1.0 + 2

=> 3.0

> 1 + 2.0

=> 3.0

 Mathematical operations result in a �oating point number except if all numbers used are
integer numbers.

This is, for example, important when you do a division ( / means “divide by”):

$ irb

> 3 / 2

=> 1

As you can see any decimal places will be just cut o�, since the result needs to be an integer number.

However, if you use �oats:

$ irb

> 3.0 / 2

=> 1.5

> 3 / 2.0

=> 1.5

 Use �oating point (decimal) numbers when doing devisions.

Exercises: How about doing some of the exercises on numbers next?


25 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Strings
A String, in programming languages, is text.

More precisely a String is an object that represents a speci�c text. E.g. your name, represented in
Ruby, is one String. The title of this text is another String, and so is this paragraph, and this full text in
its entirety.

In web applications Strings are everywhere. In fact they’re used by far more often than numbers. That
probably is because most applications that we deal with on a daily basis are dealing with text
messages (Email, Facebook, Twitter, …) or descriptions of things (Amazon, Ebay, …).

Did you ever use a web application that is a complicated calculator app, and mostly deals with
numbers? There you go :)

In Ruby there are a couple of �exible ways to create Strings, but the most simple and by far most
common way is to simply enclose some characters in quotes:

"This is one String!"

'And this is another one.'

 Strings can be de�ned by enclosing any text with single or double quotes.

Both of these are good to use. Technically they are almost the same, except for one important feature
called “String interpolation”, which we’ll explain later.

Things you can do with Strings

Here are a few things you can do with Strings.

You can glue them together by using + . We also call this concatenation (http://www.wikiwand.com
/en/Concatenation).

$ irb

> "snow" + "ball"

=> "snowball"

> "hi" + "hi" + "hi"

=> "hihihi"

The last operation can also be done by using * , like so:

26 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> "hi" * 3

=> "hihihi"

I.e. multiplying a String by a number in Ruby means repeating the String as many times.

The following examples are worth noting, too:

$ irb

> "1" + "1" + "1"

=> "111"

> "1" * 3

=> "111"

This demonstrates that Ruby behaves the same for Strings that contain nothing but numbers.

Some other things that you can do with Strings that you can try yourself in irb :

> "hello".upcase

=> "HELLO"

> "hello".capitalize

=> "Hello"

> "hello".length

=> 5

> "hello".reverse

=> "olleh"

 These last few examples are examples of “calling methods on objects that are Strings”.
Methods are “behaviour” that objects are capable of. We’ll explain methods, and how they
relate to objects more in just a few chapters.

Exercises: How about doing some of the exercises on Strings next?

History

27 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

The reason why pieces of text, in the context of programming languages, usually are not referred to
as “text”, but instead with the slightly odd term “String” is a historical, and technical one:

In early programming languages Strings were implemented as lists of characters, and programmers
had to deal with them as such: imagine pellets lined up on a String. One had to take care of nasty
things like manually managing the length of the character list, and inserting a couple characters in the
middle of such a list was quite a complicated operation.

When languages evolved over time they made things like this easier for developers, and added built-in
abstractions for the concept of “Strings”. So the name sticked, and resembles the way programmers
had thought about text before: as characters lined up on Strings.

 Luckily, nowadays, in Ruby and any other modern language, you can just think about Strings
as text.

True, False, and Nil


There are three more “things” that we’d like to mention quickly, just because you’ll see quite
frequently: These are true , false , and nil .

The �rst two, true and false are just what you think they are:

 The object true represents “truth”, while false represents the opposite of it.

In other words, in Ruby, true and false are also “things”, just like numbers, Strings, Arrays, and
Hashes. You can assign them to variables, pass them around, and otherwise use them. They’re fairly
simple things, but they’re also very useful.

The third object nil represents “nothing”. Yeah, that’s right. In Ruby there’s a “thing” that represents
the absence of things. This might be a interesting topic to discuss on a philosophical level, but for now
we’ll just see how it works in Ruby.

 The object nil represents “nothing”.

You’ll see later that every operation (“method”) in Ruby always returns exactly one thing (i.e. one
object), and that’s why there needs to be a “thing” that represents “nothing”.

This will start to feel pretty natural to you pretty soon.

Symbols
Symbols are like strings, except they are code.

28 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Symbols are a rather strange concept to be honest, and we only introduce them because symbols are
used so often and widely that you’ll very likely �nd them used in code elsewhere. For your �rst steps
in learning programming we would not necessarily need them.

A symbol is written like this: :something

I.e. there is a word that is preceded by a colon. This means that normally symbols do not contain
spaces. Instead, if we have symbols that consist of multiple words we would concatenate them with
underscores, like so: :another_funny_symbol

 A symbol is created by adding a colon in front of a word.

So when to use strings, and when to use symbols?

There’s actually no perfectly clear line or simple de�nition.

One rule of thumb is that if the text at hand is “data”, then use a string. If it’s code, then use a
symbol, especially when used as keys in hashes (see below).

Another way of looking at symbols is that they aren’t really text, even though they read well.
Instead they are unique identi�ers, like numbers, or bar codes. While strings represent data that
can change, symbols represent unique values, which are static.

And more technically, if you use strings that contain the same text in your code multiple times,
then a new string object will be created every time. E.g. if you do puts "Hello!" 10 times then 10
actual string objects will be created (and then discarded, because they’re not being used any
longer). On the other hand, if you’d use a symbol for this and do puts :hello 10 times, then only
one single object will be created, and re-used.

 Symbols are unique identi�ers that are considered code, not data.

If you �nd all of this confusing, don’t worry, many people do. You’ll understand symbols better once
you get to use some of them in your code. For now you can think of them as a special, limited
variation of Strings (text).

 Symbols are a special, limited variation of Strings.

The technical di�erence


Skip the following unless you’re really curious about the underlying technical di�erence between
Strings and Symbols.

Try this in IRB:

29 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> "a string".object_id

=> 70358630335100

> "a string".object_id

=> 70358640625960

> "a string".object_id

=> 70358644379620

As you can see, even though the 3 Strings created are exactly the same, every new String created has
a di�erent object_id : They’re actually di�erent objects, even though they contain the same text.

With Symbols however:

$ irb

> :a_symbol.object_id

=> 1086748

> :a_symbol.object_id

=> 1086748

> :a_symbol.object_id

=> 1086748

We now get the same object_id for each of the Symbols, meaning they’re referring to the exact same
object.

The object_id is a unique id that Ruby uses internally in order to keep track of all the objects that are
�ying around in the universe that makes up your program. E.g. Ruby needs to know which objects are
still being useful, and which ones can be cleaned up and thrown away. The object_id is a way to
identify each and any object by a unique id.

By true , false , and nil (as well as all numbers) also behave this way: Whenever you use these in
your code you’ll get the same object. Try it in IRB and check their object_id .

Let’s move on though.

Arrays
Arrays are like bags that contain things

While numbers, Strings, true , false , and nil all represent simple, primitive things, Arrays are more
interesting, and very useful.

Arrays are things that store (or “hold”) other things. You can think of an Array as a collection or list of
30 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

things. Or better yet, as a bag that you can throw things in: The bag itself is a thing (an object), too.

 An Array is an object that stores other objects.

An Array is created by separating values by commas, and enclosing this list with square brackets, like
so:

[1, 2, 3]

This is a simple Array that holds three numbers.

 An Array is created by listing objects, separated by commas, and enclosed by square


brackets.

Arrays can contain all kinds of things:

["A string", 1, true, :symbol, 2]

This creates an Array with 5 elements, i.e. a bag that contains 5 things: a string, a number, true , a
symbol, and another number.

 Arrays can contain all kinds of objects.

Note that in Ruby Arrays always keep their order: Unlike a real bag, where, when you throw in a bunch
of apples, they might come out in a di�erent order, an Array always keeps its objects in the same
de�ned order (unless you do something to change the order).

Also note that in Ruby you can store any kind of object in an Array. For example, you can also store
Arrays in an Array: that’s a 2-dimensional Array, like a table that has many rows, and each row has
many cells (“things”).

 Arrays have a de�ned order, and can store all kinds of objects.

Retrieving an element from an Array


Arrays can be used in a lot of di�erent, and useful ways, but the most basic one is to retrieve a certain
element by the way of referring to its position: Please get me the element at position 1!

In Ruby, you can do this with square brackets like so:

31 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

words = ["one", "two", "three"]

puts words[1]

Do you recognize how we use a variable to assign a name to our Array here?

words[1] means: from the Array words get the element at position 1 . puts will then print this value
out to the screen. (By the way puts stands for “(out-) put string”.)

So, as you can see square brackets [] mean di�erent things when used in di�erent contexts. The
same is true for other punctuation, too.

In our case here the square brackets on the �rst line are used to create an Array object with the given
elements. On the second line the square brackets are now appended to a variable name. This means
we want look up an element from the Array that (at this moment) is called words (i.e. assigned to the
variable words ).

 Punctuation (such as square brackets) has di�erent meanings in di�erent contexts.

Arrays are zero based


What do you think our example code will print out to the terminal? Funnily, it’s two , and not one .
Huh?

The reason for this is: The �rst position in an Array is 0, not 1. So the position 1 refers to the second
element, not the �rst one.

In programming books and the Ruby documentation you’ll often �nd the word “index” to be used
instead of “position” in this context.

 Arrays start with the index 0, not 1.

Appending an element to an Array


In order to add an element to the end of an existing Array you can use the operator << , called “shovel
operator”, like so:

words = ["one", "two", "three"]

words << "four"

puts words[3]

This prints out four : The string "four" has been “shoveled” into, that means, appended to the Array.
And since it now sits at position 3 we can access it using words[3] .

32 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Setting an element to a position


You can also set an element to a speci�c index, like so:

words = ["one", "two", "three"]

words[3] = "four"

puts words[3]

This also prints out four .

You could also overwrite existing elements the same way. For example this would set the word "uno"
to the position 0 (i.e. overwrite "one" ):

words = ["one", "two", "three"]

words[0] = "uno"

puts words[0]

So, this would now output uno .

 On formatting: Note that there are no spaces inside the square brackets, and there’s one
space after each comma.

Missing elements
What if we try to retrieve an element that does not exist, for example the element at the fourth, or
�fth position (index)?

Right, we get back nil , meaning “nothing”:

> words = ["one", "two", "three"]

> words[3]

=> nil

> words[4]

=> nil

You’ll learn later that every operation (“method”) in Ruby always returns exactly one thing (i.e. one
object), and that’s why there needs to be a “thing” that represents “nothing”.

This will start to feel pretty natural to you pretty soon.

Nested Arrays
33 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

As said before, Arrays can contain all sorts of things. So, they can also contain more Arrays.

This is quite a common thing to use when you need to represent some data that has the
characteristics of a table, like an spreadsheet.

The outer Array represents the table, and each inner Array represents one row. Each value then
represents a cell. For example:

[1, 2, 3],

[4, 5, 6],

[7, 8, 9],

[0]

This is a nested Array that represents the structure of number keys on a phone.

Things you can do with Arrays


Here are a few things you can do with Arrays.

Look at them, and play with them in irb . Don’t necessarily try to memorize all of them … you can
always look things up in the documentation when you actually need these. It might be useful if you’ve
seen some of them before though.

Funnily, you can “calculate” with Arrays. Remember set theory from your math classes? This is pretty
similar.

You can add Arrays:

$ irb

> [1, 2] + [3, 4]

=> [1, 2, 3, 4]

Subtract them from each other:

$ irb

> [:one, :two, :three, :four] - [:three, :four]

=> [:one, :two]

Multiply with a number:

34 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> ["Ruby", "Monstas"] * 3

=> ["Ruby", "Monstas", "Ruby", "Monstas", "Ruby", "Monstas"]

And �nd the intersection:

$ irb

> [1, 2, 3] & [2, 3, 4]

=> [2, 3]

first and last are alternative ways to retrieve the �rst and last element:

$ irb

> [1, 2, 3].first

> [1, 2, 3].last

Some other things that you can do with Arrays that you can try yourself in irb :

> [1, 2, 3].length

=> 3

> [3, 1, 2].sort

=> [1, 2, 3]

> [1, nil, 2, 3, nil].compact

=> [1, 2, 3]

> [1, 2, 3].index(3)

=> 2

> [1, 2, 3, 4].rotate(2)

=> [3, 4, 1, 2]

> [[1, 2, 3], [4, 5, 6], [7, 8, 9]].transpose

=> [[1, 4, 7], [2, 5, 8], [3, 6, 9]]

35 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

In these examples compact removes all nil values from the Array. transpose works with a nested
Array and “�ips” the table, i.e. turns columns into rows, and rows into columns.

Exercises: Now would be a good time to do some of the exercises on Arrays.

Hashes
Dictionaries: look up one thing by another

Hashes are another very useful, and widely used kind of thing that can be used to store other objects.

Unlike arrays which are mere lists, Hashes are like dictionaries:

You can use them to look up one thing by another thing. We say: we look up a value from a Hash
using a key. Or one could say: Please get me the value that is associated with this key.

Imagine a real dictionary that translates from English to German. When you look up the English word
“hello” then you’ll �nd the German “Hallo”. When you look up “one” then you’ll �nd “eins”, and so on.
The authors of this dictionary have assigned a German word (a value) to an English word (the key).

Hashes work pretty much like this.

 A Hash assigns values to keys, so that values can be looked up by their key.

We also refer to a value that is assigned to a key as key/value pairs. A Hash can have as many
key/value pairs as you like.

Creating a Hash
In Ruby you can create a Hash by assigning a key to a value with => , separate these key/value pairs
with commas, and enclose the whole thing with curly braces.

This is how it looks:

{ "one" => "eins", "two" => "zwei", "three" => "drei" }

This de�nes a Hash that contains 3 key/value pairs, meaning that we can look up three values (the
strings "eins" , "zwei" , and "drei" ) using three di�erent keys (the strings "one" , "two" , and
"three" ).

By the way, the Ruby community has come up with the name hash rocket for the bit of syntax =>
which separates a key from a value, … we think that is pretty cool to know :)

 A Hash is created by listing key/value pairs, separated by hash rockets, and enclosed by
curly braces.

36 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Looking up a value
Now, how do you actually look up the value that is associated with the key "one" ?

Just like with Arrays you use sqare brackets, but instead of passing a number indicating the position
you now pass the key. Like so:

dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }

puts dictionary["one"]

Do you reckognize how we, on the second line, use a variable name to refer to the Hash de�ned on
the �rst line?

In this example, dictionary is a Hash de�ned on the �rst line. ["one"] looks up the value associated
to the key "one" , which is "eins" . This value will be passed to puts which outputs it to the screen.

Setting a key to a value


Also, just like with Arrays, there’s a way to set key/value pairs on an existing Hash:

dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }

dictionary["zero"] = "null"

puts dictionary["zero"]

This prints out null .

You could also overwrite existing key/values the same way. For example this would set the word
"uno" to the key "one" (i.e. overwrite the existing pair with the value "eins" ):

dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }

dictionary["one"] = "uno"

puts dictionary["one"]

So, this would now output uno .

Any kind of objects


You can use any kind of object as keys, and you can store any kind of object as values.

For example, these are all valid Hashes, too:

37 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

{ 1 => "eins", 2 => "zwei", 3 => "drei" }

{ :one => "eins", :two => "zwei", :three => "drei" }

{ "weights" => ["pound", "kilogram"], "lengths" => ["meter", "mile"] }

{ :de => { :one => "eins", :two => "zwei", :three => "drei" } }

The �rst example uses numbers as keys, while the second one uses Symbols, which is quite a
common thing to do in Ruby.

In the third example you can see that one can use Arrays as values in Hashes. So if you’d look up the
key "weights" you’d now get an Array back.

Not quite sure where you’d use a Hash like the third line in real code, but the last line is actually pretty
darn close to what Rails uses for translating strings to di�erent languages:

It is also an example of a nested Hash. There’s another Hash associated (stored) as a value for the key
:de (representing the language German). And this other Hash now has three key/value pairs. So a
Rails programmer could look up how to translate “one” to German, and get “eins” back.

 Hashes can use any kind of objects as keys and values.

 On formatting: Note that there’s one space inside the curly braces on both sides, around the
=> Hash rocket, and after each comma. But there are, again, no spaces inside that square
brackets [] that de�ne the Arrays on the third line.

Missing values
What happens if we try to look up a key that does not exist?

Again, just as with Arrays, we’ll get back nil , meaning “nothing”:

$ irb

> dictionary = { "one" => "eins", "two" => "zwei", "three" => "drei" }

> dictionary["four"]

=> nil

Does this make sense?

Things you can do with Hashes


The main purpose of a Hash is being able to lookup a value by a key.

However, here are a few other things you can do with Hashes, too.

38 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Again, look at them, and play with them in irb . Don’t necessarily put too much e�ort into
memorizing all of them …

You can merge two Hashes:

$ irb

> { "one" => "eins" }.merge({ "two" => "zwei" })

=> { "one" => "eins", "two" => "zwei" }

fetch does just the same as the square bracket lookup [] discussed before, but it will raise an error
if the key is not de�ned:

$ irb

> dictionary = { "one" => "eins" }

> dictionary.fetch("one")

=> "eins"

> dictionary.fetch("two")

KeyError: key not found: "two"

keys returns an Array with all the keys that a Hash knows:

$ irb

> dictionary = { "one" => "eins", "two" => "zwei" }

> dictionary.keys

=> ["one", "two"]

length and size both tell how many key/value pairs the Hash has:

$ irb

> dictionary = { "one" => "eins", "two" => "zwei" }

> dictionary.length

=> 2

> dictionary.size

=> 2

Exercises: Now would be a good time to do some of the exercises on Hashes.

Hash syntax confusion


39 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

You can skip the following and jump right to the chapter Variables, or you can keep reading if you’re
curious.

We’ve found it’s important for us to explain the following somewhere in our book, because many
online resources use another, alternative syntax for de�ning Hashes.

The term syntax, in programming, refers to ways to use punctuation in order to (amongst other
things) create objects.

E.g. the fact that we can use square brackets [] and commas , in order to de�ne Arrays, and curly
braces {} and hash rockets => in order to de�ne Hashes, is part of Ruby’s syntax.

Today, there are two di�erent syntaxes for de�ning Hashes with curly braces, and they have the
potential to confuse newcomers a lot.

There’s an old-style one, and a new, modern one.

 We use the old syntax, and ignore the new one, for now.

Here’s why:

Up to a certain version of Ruby the syntax that uses hash rockets was the only syntax to create
Hashes, and it works the same for all Hashes no matter what kinds of objects you use as keys.

Then, a few years back, a new syntax was introduced. Many Ruby programmers love to use it, because
it takes a little less space, and it also looks a lot like JSON, which is a data format that is widely used in
web applications.

The new Hash syntax looks like this:

{ one: "eins", two: "zwei", three: "drei" }

Using this syntax we tell Ruby that we want the keys to be symbols.

Hmmmm? We just learned that Symbols are de�ned by prepending a word with a colon like :one ,
right?

Well, yes, correct, but that’s just how it works: If you de�ne a Hash using this syntax, then you’ll get a
Hash that has Symbols as keys.

We found the new syntax pretty confusing for beginners: It is slightly less explicit and obvious, and
you have to learn another piece of information. That’s why we simply ignore it in our study groups
while we learn what Hashes are and how you can use them.

Once you feel comfortable using Hashes, you can make your own decision, and start using the
modern syntax if you like it better.

In the meanwhile, whenever you see a Hash using the new syntax somewhere else, you now know
what it means, and where to look it up. Simply remember that these two Hashes are exactly the same:
40 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

{ :one => "eins", :two => "zwei", :three => "drei" }

{ one: "eins", two: "zwei", three: "drei" }

Objects, Classes, Methods


We’ve talked about objects quite a bit now, merely using that term as a synomym for “things”. You’ve
learned to do stu� with simple objects such as numbers and Strings, and the data structures Arrays
and Hashes. You’ve also learned what a method is, how to de�ne and use them, and how to pass
things to them, and get others back.

We’re also prepared well enough to have a closer look at objects, classes (types of things) and
methods, and how they relate to each other.

As a sidenote, you may have heard the following. Rubyist love saying it:

 In Ruby everything is an object.

Actually, this is a little bit of a lie. Even though it’s being said so often, it isn’t completely true: not
everything is an object. There are a few things that are not objects.

But almost everything is, and that’s good enough to know for now.

 In Ruby almost everything is an object :)

(Just in case you want to out-smart people at your local Ruby user group though, remember to ask
“Really? Is an if statement an object or a method? How about self?”)

Objects have classes


As mentioned before when you run a Ruby program a little universe (space, scope) is being created,
and populated with concrete objects (things) as de�ned by your program. These things interact, and
do useful stu�, using certain methods that you call.

Also, each concrete thing (object) is an instance of a general idea or type, and these ideas are called
classes.

You can see that objects have classes when you open IRB in your terminal and ask an object for its
class:

41 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> "this is a string".class

=> String

Objects are concrete instances (manifestations) of classes.

That means that the following sentence is true: In Ruby, "a string" is a String .

Hmmmm, yeah, we kinda knew that already, right. However, you can also ask the same question in
Ruby:

$ irb

> "this is a string".is_a?(String)

=> true

So, the actual string knows that it is a String , which in Ruby means that it is an instance of the class
String . You can do this for any object. E.g. 1.is_a?(Numeric) , also returns true . This is pretty cool.

We also say that an object is an instance of its class. Let’s see what that means.

Classes create objects


Objects are instances of classes.

Classes are kind of blue prints for the concrete objects. Every time a concrete object (such as the
String "one string" , the String "another string" , the String "yet another string" , and so on …) is
created:

We say that the class is instantiated: an object is created from it.

What does that mean?

Classes have a bunch of characteristics, but most importantly, every class de�nes a number of
methods, which are speci�c to this type of thing (e.g. a String).

Now, every time a new object is created (“instantiated”) from this class this new object get (“inherits”)
all of these methods.

Objects inherit methods from their classes.

That’s right. Objects have their own methods attached to them.

We’ll explain more about methods that belong to objects in the next chapter. And you’ll see how you
can de�ne methods to your own classes, so they’re then available on your objects when we start
de�ning our �rst, own class.
42 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

But for now we can already point out that all concrete Strings that you use in your code will all have
the same methods de�ned (attached to them) … because they’re all created (instantiated) from the
the same class.

You can have a look at all the methods that the class String de�nes on Ruby’s documentation page
(http://ruby-doc.org/core-2.2.0/String.html) for this class.

Let’s see how we can use these methods.

Objects have methods


Methods are an object’s behaviour

Objects have methods, allowing us to do interesting stu� with them. An object’s methods are things
that the object can do.

Think about a person, like, a friend of yours. You can ask this person for their name (call a method),
and they’ll tell you (return it to you). Their name is a piece of knowledge that this person has, and the
ability to tell it to you (respond to your question) is a piece of behaviour (a method) they have.

We could also ask them to make, and bring a cup of tea for us. Or we could ask them to remember a
phone number, or email password.

As Rubyists we actually say that we “talk to objects”, or “send messages” to them: We do so by using
(calling) methods that they respond to.

So, what can an object do?

That depends on their class (type). Numbers can do things that are useful for numbers, obviously. You
can do math, and ask them about their mathematical properties (e.g. “Are you an odd number?”).
Strings (text) come with way more methods, and they’re often related to text transformations.

 Methods add behaviour that is useful to have for a particular type of object.

We’ve already used some methods in the previous chapters: E.g. "hello".upcase calls the method
upcase on the String "hello" .

Also, class and is_a? are methods de�ned on all objects in Ruby, and therefore also de�ned on the
String "a string" : "a string".is_a?(String) answers with true .

 Some methods, such as class , is_a? , are de�ned on all objects.

Let’s move on to see how we can use (call) these methods though.

Calling methods
43 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

In Ruby, methods that belong to (are de�ned on) objects can be used (called) by adding a dot, and
then the method name, like so:

object.method

That’s like saying Hey object, please do [method].

Let’s try that out in IRB.

For example, the class String de�nes methods like upcase (Give me an uppercase version of yours),
downcase (What’s the downcased version of yours), and length (Hey string, what’s your length?).

Here’s how we can call them:

$ irb

> name = "Ruby Monstas"

> name.upcase

=> "RUBY MONSTAS"

> name.downcase

=> "ruby monstas"

> name.length

=> 12

And so on.

In other words, you �rst address, or mention, the object that you want to talk to, and then, with the
dot . , “send a message” to the object by specifying the method name. We also say: “you call the
method upcase on the string”.

 A dot is used to call a method on an object.

Imagine the string name is a person you can talk to. You can ask questions by “sending a message” to
them, and they’ll respond by sending (returning) something back. The term “sending messages”
actually is used instead of “calling a method” in programming, and speci�cally in Ruby.

So, you can ask the string to hand you an “upcased” version of itself. And it responds by doing so. Or
you can ask it for its length, and it responds by returning the number 12 to you.

You can have a look at all the methods that the class String de�nes (responds to) on Ruby’s
documentation page for this class (http://ruby-doc.org/core-2.2.0/String.html).

Most methods in Ruby work this way: You ask an object to return a bit of information about itself
(such as a String’s length), or a modi�ed (transformed) version of itself (such as a downcased version
of the String).

44 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

 Most methods are questions, and return a relevant value.

Others modify the object itself, and some have so called side-e�ects, and modify something else, e.g.
puts and p both output something to the screen. Other methods might save �les, send emails, or
store things to a database.

 Some methods are commands, and change the object, or the system (e.g. by saving a �le).

Passing arguments
Extra information needed

Sometimes an object needs a little bit of extra information in order to do what you ask for.

For example the class String de�nes the method delete which returns another String with some of
the characters deleted. In order to do so, of course, it needs to know which characters we’d like to
remove.

We can pass things by appending parentheses () to the method call (the name). We can then include
the extra bit of information needed (in our case another string) inside the parentheses like so:

$ irb

> name = "Ruby Monstas"

> name.delete("by Mo")

=> "Runstas"

Hm. Not sure what “Runstas” means. Ideas? Let us know.

Anyhow, another example for a method that needs an argument is the method prepend on Strings.
This method returns a new String with the given String prepended:

> name = "Ruby Monstas"

> name.prepend("Oh, hello, ")

=> "Oh, hello, Ruby Monstas"

These extra bits of information are called arguments. We’ll discuss them more once we get to de�ne
our own methods.

Not all methods need these extra bits of information (arguments) in order to do their job. E.g. the
method length on Strings knows the length of their String just so (because it knows its String).
Sometimes they need one or more arguments though.
45 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

So how do you know?

You might remember, over time, for some important methods, but most of us also check the
documentation quite frequently, too. Some times it’s just �ne to try it out quickly, and only check the
documentation if it does not work as expected.

Listing methods
As said above, if you are curious what methods are de�ned on a certain object, then you can check
the Ruby documentation (http://ruby-doc.org/core-2.2.0/) for this class. (Usually the right page
conveniently shows up at the top when you google for “ruby” and the class name.)

However, you can also quickly pop into IRB and ask the object for its methods. That’s right, methods is
a method de�ned on all objects (just like class , and is_a? ).

When you call it then it will return (respond with) an Array with all the method names that the object
has.

It makes sense to sort the Array, so it is easier to read. Like so:

$ irb

> "Ruby Monstas".methods.sort

=> [:*, :+, :<, :>, :[], :class, :downcase, :delete, :include?, :is_a?, :length, :prepend, :start_with?

Yep, the method names come as Symbols, because they’re considered code.

If you do this yourself, you’ll see that the String actually has a lot more methods. Many of these
actually aren’t used very often, but some are quite useful. We have stripped the Array down a little,
because we want to talk about some of these methods more.

Chaining method calls


Btw the code above also demonstrates that methods can be “chained”: When we call a method on an
object it will return another object to us. We can then immediately call another method on that new
object, and so on.

In our example above the method methods returns a Array of names. And Arrays respond to (have)
the method sort , so we can call this method immediately, by using another dot.

We could chain some of the method calls from our String example above like so:

46 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> name = "Ruby Monstas"

> name.prepend("Oh, hello, ").upcase

=> "OH, HELLO, RUBY MONSTAS"

So we have a String "Ruby Monstas" , prepend another String to it, which returns a new String "Oh,
hello, Ruby Monstas" , on which we immediately call the method upcase.

Pretty handy.

As you can see Ruby will �rst evaluate the bit name.prepend("Oh, hello, ") . It needs to do that so it
knows the object (the new String) that is going to be returned from this, so it can then call the method
upcase on it.

Does this make sense?

Predicate methods
If you check the list of methods on our String above you see that in Ruby we can have methods that
end with a question mark ? . What’s up with that?

By convention, in Ruby, these methods return either true or false . For example, we can ask a
number if it is even or odd:

$ irb

> 5.odd?

=> true

> 5.even?

=> false

This makes them read like a question, which is pretty cool.

Or you can ask the number if it’s between two other numbers. Obviously this methods needs us to
pass those two other numbers. So now we also have an example of a method that takes two
arguments:

47 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

> 5.between?(1, 10)

=> true

> 5.between?(11, 20)

=> false

These methods are called predicate methods in Ruby. Not quite sure why, maybe because of the
historical math context of programming.

 Predicate methods that end with a question mark ? return either true or false .

Strings also de�ne some predicate methods:

> name = "Ruby Monstas"

> name.start_with?("R")

=> true

> name.start_with?("a")

=> false

Do you also think it’s kinda odd that name.start_with?("a") reads almost like English, but not quite?
Maybe the method could have been named starts_with? instead, right? That’s true. This is because
Matz, the creator of Ruby, is not a native English speaker, and some names sound right in Japanese
when translated literally.

Also:

> name = "Ruby Monstas"

> name.include?("by")

=> true

> name.include?("r")

=> false

When we check what methods there are de�ned on a number, we �nd some with the same name, but
also di�erent ones:

48 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> 1.methods.sort

=> [:*, :+, :-, :/, :between?, :even?, :odd?, :zero?]

Let’s try zero? :

> 0.zero?

=> true

> 1.zero?

=> false

Arrays have the methods include? , and Hashes respond to key? :

> [1, 2].include?(1)

=> true

> [1, 2].include?(3)

=> false

> { "eins" => "one" }.key?("eins")

=> true

> { "eins" => "one" }.key?("zwei")

=> false

Oh by the way, if you’re curious why operators like * , + , - and so on are also listed here, check the
chapter that explains that operators are methods, too.

Bang Methods
All of the examples that we’ve discussed before have one thing in common:

They are questions, and do not modify the object they are called on.

For example:

49 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

name = "Ruby Monstas"

puts name.downcase

puts name

This will output:

ruby monstas

Ruby Monstas

As you can see the method downcase has returned a new String, which is the lowercase version of the
String that the method is being called on. When we output the original String on the next line, we can
then see that it’s still the same: The method downcase does not modify the String.

However, there also are variants of some of these methods, which end in an exclamation mark ! .
These methods are called “bang methods”, and they usually modify the object that they’re being
called on.

 Bang methods end with an exlamation mark, and often modify the object they are called on.

For example, next to the method downcase Strings also have a method downcase! .

Let’s try that:

name = "Ruby Monstas"

puts name.downcase!

puts name

This will output:

ruby monstas

ruby monstas

As you can see calling the method downcase! on the second line has modi�ed the String itself (the
object that name refers to), and also returned the new downcased version.

Nowadays programmers have learned that using these methods has a number of disadvantages, and
usually should be avoided, unless there are very good reasons for it (usually, there are none).

 Use bang methods with caution.

50 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

We mostly mention these methods because you might see them used elsewhere.

Writing Methods
A named block of code that takes input and returns output

Everything in programming is about data, and doing interesting things with it. If you think about
Twitter, it essentially takes 140 characters of text (which is data) from their users and displays it to
others.

You have already learned about the most important primitive (simple) types of data in Ruby: numbers,
strings, true, false and nil. And we’ve had a look at the two most common data structures, Arrays and
Hashes.

All of this is about the data part. Methods on the other hand are about the doing interesting things
part.

In this chapter we’ll have a closer look at the anatomy of a method, and you’ll learn how to implement,
and use, your own methods.

Methods de�ne behaviour


Methods are all about de�ning behaviour, so that they can be applied to di�erent bits of data in
di�erent contexts easily.

For example, there are methods that do things like: transforming a String, sorting a list, reading a CSV
or Excel �le, sending an email, signing in to Facebook, sending a Tweet.

Another way of putting this is: Methods are a way of assigning a name to a certain piece of code. Just
like a variable allows to “look up” or refer to the object that the name was assigned to … methods
allow to execute their code.

 Variables name things, methods name behaviour (code).

Methods make code re-usable, by the way of packaging (“encapsulating”) code and sticking a name on
it.

As you have seen Ruby comes with lots of methods prede�ned - written by experienced
programmers. So, unless you’re studying computer science and you’re faced with the exercise of
implementing your own, complicated sorting algorithms for data collections, … you’ll just use the
method sort that already comes de�ned for Arrays in Ruby out of the box.

Ok, let’s see what makes up a method, and how we can de�ne our own ones.

What makes a method


51 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

There are four things that constitute a method:

a name
a block of code
(optionally) accepting input
returning output

Not all methods actually need input (so they don’t take any), and not always do we care about the
output that a method returns.

Imagine a vending machine where you can chip in some money, press some buttons, and the
machine will spin a few gears and wheels, and spit out the chocolate bar you were after.

If the vending machine was a method, then your money, as well as the buttons you press are the
input. The way the machine internally spins certain mechanics is the block of code, the stu� it does
internally. And the product that it dispenses is the return value.

Although this would be an odd thing to mention to a non-programmer, we could say that a vending
machine is a way of “transforming” money and data into chocolate.

Methods are a lot like that.

 Methods have a name, take some input, do something with it, and return a result.

Programmers usually don’t use the term “input” in this context. Instead we say that a method accepts
a number of arguments (pieces of input). And instead of “output” we use the term return value: the
thing that we get back from the method.

 A method’s input is referred to as “arguments”, while its output is called a “return value”.

This will become more clear in the following chapters. Let’s de�ne a method next.

De�ning a method
So far you have seen methods that “belong” to objects, or, in other words, are de�ned on objects, and
can be called on objects. E.g. you have seen the method downcase which is de�ned on every string.

However, Ruby also knows methods that are not de�ned on any of these objects. They’re sort of
“stand alone” methods.

For example, you can try this in irb :

52 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

$ irb

> is_a?(Object)

true

We’ll use this type of methods in this chapter because we want to focus on the characteristics of
methods. If you’re curious what’s up with them have a look at the bonus chapter about the top-level
object. Later when you learn how to de�ne your own classes we also look at de�ning methods for
these.

Ok, let’s get started.

Suppose we need to de�ne a simple method that takes a number, adds the number 2 to it, and
returns the result. Here’s how we can do that:

def add_two(number)

number + 2

end

This de�nes a method. It does not use it, yet: You only build and place that vending machine, so it can
be used (by yourself, or others) later.

Let’s walk through this method de�nition step by step:

Ruby will start reading the code at the top, and �nd the keyword def . This tells Ruby that we’re about
to de�ne a new method.

Methods need a name, so Ruby looks for it next, and �nds the word add_two .

Ruby then checks if we de�ne anything to “input” to the method (remember, this is optional). She
�nds the parentheses, and knows that we’re about to de�ne a list of things that can be given to the
method. This list is called an argument list.

 An argument list de�nes names for objects passed to the method, enclosed by parentheses
right after the method name.

In our case the argument list has one single argument number , which means our method can accept
one single thing (object).

The next line is the block of code that our method has (“encapsulates”). This is also referred to as the
method body. In our case that’s just one single line because the operation that our method
encapsulates is very simple. Other methods (think of sort , de�ned on Arrays) would require more
code, and are longer.

Inside the method body the arguments are known as local variables: You can see how the code in our
method body uses the variable name number .
53 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Finally the keyword end tells Ruby that we’re done with the method body, and the method de�nition.

All we’ve done so far is de�ning the method, we haven’t used it for anything, yet. We’ll do that in the
next chapter.

 On formatting: Note that the keywords def and end sit on the same level, while the
method body is indented by two spaces. Also, there are no space before or inside the
argument list, i.e. the () parentheses.

Using (calling) a method


Once de�ned we can use our method.

As programmers we usually say that we “call” a method. This means we ask Ruby to execute the code
that the method body has, with some given arguments (input), if any.

Here’s how that looks:

def add_two(number)

number + 2

end

puts add_two(3)

Let’s inspect what’s happening here under the microscope. If you don’t understand each part of this
just yet, don’t worry, we’ll get back to all of this.

On the �rst three lines Ruby de�nes the method add_two as discussed above.

On the next line Ruby will look at the bit add_two(3) �rst. She recognizes that we are referring to
a method de�ned earlier, and this will tell her we want to call (execute, use) this method.
In order to do so she �rst needs to look at what’s inside the parantheses () so she can pass it on.
She �nds the 3 and creates a new object (number) for it.
Now Ruby is ready to actually call (execute, use) the method, passing the number 3 .

So Ruby now deviates from the normal �ow, which just goes from top to bottom in our �le. Instead
she now jumps into the method body.

In this moment she now assigns the number 3 to a local variable number before she starts executing
the method body.

That’s right. This is how method arguments work:

When a method is called and objects are passed as arguments, then Ruby implicitely de�nes local
variables with the argument names. She assigns the passed objects to the variable names that are in
54 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

the argument list. These local variables are then available in the method body.

In our case we have just one argument number . So we get one local variable number with the object 3
assigned (because that’s the object passed when we called the method).

You can imagine the method body now reads like this:

number = 3

number + 2

Ok, so we’re inside the method body now:

Ruby will now execute (evaluate, run) the method body (again, going from top to bottom), which
in our case is just a single line with the expression number + 2 .
Because number is assigned 3 this expression will evaluate to 5 .
Since this line of code is the last line in the method body, the value 5 also is the value returned
from the method call.

So Ruby now jumps back out of the method. The expression add_two(3) has just returned the object
5 . Imagine the last line now reads like this instead:

puts 5

And that will now print the number 5 to the screen.

Let’s have a closer look at that thing with the return value (“output”), as we just rushed over that a
little.

Return values
In Ruby, a method always return exactly one single thing (an object).

The returned object can be anything, but a method can only return one thing, and it also always
returns something.

 Every method always returns exactly one object.

The object returned could be the object nil , meaning “nothing”, but it still is an object. Also, in order
to return a bunch of things at once we could return an Array that holds the things that we are
interested in, but the Array itself is just one object.

Also note that in Ruby we do not have to use the statement return , as in other languages. In fact,
most Ruby code does not use the keyword return at all.

55 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This is extremely convenient, but it is also something we need to learn:

If we don’t do anything else, then a method will return the value that was returned from the last
evaluated statement. Most often, this is the last line in the method body.

This is important to understand. Please read that sentence again:

 If we don’t do anything else, then a method will return the return value of the last evaluated
statement.

In our example method …

def add_two(number)

number + 2

end

p add_two(3)

… the last evaluated statement is the expression number + 2 . Since in our example number is assigned
3 this expression returns the number 5 , and that is why the value returned by our method also is
5 .

If, in certain cases, we do want to “return” from the method early, then we can still do this using the
return statement. For now, you don’t need to worry about this case.

So, let’s move on :)

Scopes
Spheres of visibility, like rooms in a house

When we talked about variables we mentioned that the most common type of variables is the “local
variable”, without explaining any further why they are local. Local to what? Where? We’re �nally ready
to explain that more.

Since we have now talked about methods, we can also discuss another important concept: scopes.

Wikipedia says: “In programming, the scope of a name is the part of a program where the name is
valid: where the name can be used to refer to something else.” (slightly modi�ed to match our own
terminology)

 Names are known (or de�ned) in a certain scope, and unknown (or unde�ned) outside of
this scope.

56 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

You can think about a scope as of a sphere, a bubble, or a room (with no windows, and doors closed):
Certain names, like variable names, are “known” and “visible” inside of the room. Other names, known
and visible in another room are not known in this room, but only in the other room.

Every time there is a method call, and the �ow of execution enters the method’s body, it enters a new
scope, or “room”. Things that are “local” to this method’s scope (i.e. things that are “inside” of the
room), are only visible in this scope. Outside of it, they are unknown.

Unde�ned local variable or method


This is also a good opportunity to talk about an error message that you might see most often. E.g.
you’ll see it every time when you made a typo and misspelled a variable or method name.

Consider this code:

def add_two(number)

number + 2

end

puts add_two(3)

puts number

The line puts add_two(2) will output 5 , but the line puts number will then raise an error.

This is because the variable number that is assigned the number 3 when we call the method is a local
variable. It is local to the method’s scope. It is created when the �ow of execution enters the method.

Outside of this scope, when the �ow of execution has returned from the method the method’s scope
has been destroyed, and all local variables are gone. The local variable number is therefore not known,
and Ruby raises an error saying undefined local variable or method 'number' .

If you think about this error message for little bit, does it make sense to you?

We have silently skipped over the fact that, in Ruby, both local variable names and method names, are
written the same way: they’re just plain words. For example, here:

number = 2

puts number

number is a local variable, and it is used in the line puts number .

However, here:

57 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

def number

end

puts number

number is the name of a method. And it can be used (called) in the exact same way: puts number

This is because Ruby, when it executes a program, evaluates one statement after another. And when
it encounters a plain word like number then it will �rst check if, within the current scope, it knows a
local variable with the same name. If so, it will use the value that is associated to this variable. If
there’s no local variable with this name, then it will look for a method. If there’s also no method with
this name it will then raise the error message undefined local variable or method 'number' .

So the error message is pretty precise, but also sounds kind of convoluted. What it basically tries to
say is:

You’ve used the word “number” here, and i don’t know it (in this scope). Did you mean to use a local
variable? Or a method?

Does that make sense?

Back to the topic of local scopes. Let’s look at another example:

number = 1

def add_to(number)

number + 2

end

puts add_to(3)

What do you think the output will be? Will it be 3 , or 5 ? Something else?

If you run the code you will see that it’s 5 .

The reason for that is that we do assign the number 1 in the outer scope to a variable number , but
this variable is then never used: the only other line in the outer scope is the last line puts add_to(3) ,
and this line does not use the variable number .

Instead, when the control �ow enters the method add_to Ruby will create a new local scope, and it
will de�ne a new local variable number which is assigned the number 3 that was passed to the
method. This new variable number is local to the method’s scope, and therefore this is a di�erent
variable than the one on the very �rst line, in the outer scope.

We found the following a good metaphor for scopes:


58 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

When Ruby enters a method, it’s like she enters a shiny new room in a house. With her, she brings the
objects that are passed as arguments to the method call. In the example above she brings an object
that is the number 3 .

Now, as soon as Ruby enters the method, she sticks post-it notes on the objects, according to the
argument list from the method de�nition. In our example that is the name number . So from now on,
in this room, there’s a known local variable that has a value assigned: The object (number) 3 with the
post-it note number on it.

In our example, the outer scope and the scope of the method add_two , are two di�erent rooms, and
there are two di�erent post-it notes stuck on two di�erent numbers, which just happen to have the
same name on them.

Combining Methods
We’ve discussed how to de�ne a method, and how to call (use) it.

What if one method is not enough? What if methods need to do more complicated things?

Easy. We can call methods from other methods.

For example, we could re-write (“re-implement”) our method add_two using another method add_one ,
and simply call it twice:

def add_one(number)

number + 1

end

def add_two(number)

number = add_one(number)

add_one(number)

end

puts add_two(3)

This would output 5 just like our previous examples. Do you understand how it works?

Of course, in Ruby we could also just solve this whole thing with simply using the + operator.

However, for the sake of the example, let’s have a look how we could add a method that does the
exact same thing as the + operator, too:

59 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

def sum(number, other)

number + other

end

We can now use that method like so:

puts sum(3, 2)

Which, again, would output 5 .

Note that in this example our method sum now takes two arguments, and so, when we call (use) it, we
also need to pass two numbers (i.e. add them inside the parentheses on the last line).

Now, with this method in place we could change (“refactor”) our previous methods to use it:

def sum(number, other)

number + other

end

def add_one(number)

sum(number, 1)

end

def add_two(number)

sum(number, 2)

end

puts add_one(3)

puts add_two(3)

Again, these examples are not super realistic, as we’d probably just use the + operator in the �rst
place, in practice.

However, we think this nicely demostrates how you can use one method from another … and how
di�erent methods require di�erent numbers of arguments.

We’ll look at a more realistic example in the next chapter.

Printing things
60 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Many of the exercises that you do while doing your �rst steps with Ruby basics include running a
short Ruby program that outputs something to the terminal.

So far, we have mostly used the method puts to do that.

However, there’s another method that is even more useful when we are trying to �gure out what a
program is doing, why it is doing it, and what a certain error might be about.

This method is the method p . In order to understand p better, we want to look at another method
�rst, which is the method inspect .

The method inspect is available on any object in Ruby. It returns a string that is a representation of
the object itself: a representation that is as close as possible to the code that you use to create the
object. So inspect is useful to inspect objects, duh :)

This becomes more clear when you try it in IRB:

$ irb

> puts 5.inspect

> puts "A string".inspect

"A string"

> puts [1, 2, 3].inspect

[1, 2, 3]

As you can see the string returned from inspect is exactly the same as the Ruby code that we used to
create the object. That is really convenient.

However, typing puts something.inspect is quite a bit of work to do. That’s 12 characters to type next
to the object itself!

Therefore Ruby has a method to make our lifes easier, and does this work for us. That’s the method
p.

This method is implemented like so:

def p(object)

puts object.inspect

end

Whenever you are trying to �gure out what a certain line of code does, what’s assigned to a variable,
or what a method call returns, we recommend to use p because it tells you exactly what the thing
that you are looking at is.
61 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

puts on the other hand tries to be smart.

For example when you pass an array to puts then it will output each of the objects on a separate line:

$ irb

> something = [1, 2, 3]

> puts something

Also, the output for numbers and strings that contain numbers is exactly the same when you use
puts :

$ irb

> puts 123

123

> puts "123"

123

From the output of puts it often is not clear whether the object that you are looking it is an array that
contains numbers, or an array that contains strings, or just a long string that contains linebreaks.

In short, puts is useful when you are writing a program that is supposed to actually output
something to the screen. Like, this could be a command line tool that you write in order to make your
own life easier at your job, and that is helpful at automating some repetitive work. Or it is useful in
Ruby programming exercises :)

On the other hand p is useful when you are trying to understand what your code does, e.g. when you
are trying to �gure out a certain error.

Writing classes
Finally, our �rst own class

Since in Ruby “everything is an object”, we have worked with objects quite a bit already.

We’ve created numbers, Strings, and seen objects like true , false , and nil . We have also looked at
their class names by calling, e.g. "a string".class , and we have explored some other methods that
these objects have. We have also talked about how you can de�ne your own methods, and how you
can call them, passing arguments as required.

That means we now have all the tools that we need to �nally learn how to de�ne and use your own
62 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

classes. And this is where things suddenly become even more fun!

You can think of objects as having two things: They know stu�, and they can do something with stu�
(their own stu�, as well as the stu� that gets passed to them).

Imagine you were an object that is an instance of the class Person . Well, in a certain way, you actually
are :)

Since you are a Person , you are able to remember your own name. And you are able to do something
with it: When asked, you can tell your name to others, that is, you can return it to the “caller”, to
whoever asked.

We’ll de�ne this exact class in just a few chapters. However, before we do that, we’ll �rst look at how
to de�ne the method add_two to a class Calculator … just because we can, and because you’re
already familiar with these methods.

De�ning classes
Let’s start by creating a class Calculator , and adding some methods to it, step by step.

In Ruby, you de�ne a class like this:

class Calculator

end

That’s all. It’s not a very useful class, since it’s completely empty, but it’s a class.

 A class is de�ned using the keyword class , a name, and the keyword end .

Also, you see that the class has the name Calculator , which starts with an uppercase letter. In Ruby,
this is required, and you’d get an error if you tried to de�ne a class calculator .

Also, for class names that consist of several words the Ruby community has the convention to
separate these words by uppercase letters, as in RubyStudyGroup . This is called CamelCase, because of
the humps. Whereas for variable and method names we use underscores, and keep everything
lowercase: local_variable and method_name . This is called snake_case.

 Class names must start with an uppercase letter, and should use CamelCase. Variable and
methods names should use snake_case.

Ok, back to our class Calculator .

Since we’ve de�ned a full, valid class, we can now already use it to create a new, concrete calculator
instance, an object from it.
63 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

You can think about the instance as the concrete calculator object that you can hold in your hands,
and use to do actual calculations. The class on the other hand is more like the idea or concept of a
calculator, like the idea of it that you have when you order a calculator online.

Ok, here’s how to do create a new, concrete instance from our class:

Calculator.new

That’s right. new is a method, and it is de�ned on the class itself (which, as you might remember, is
also an object, so it can have methods). This method creates a new instance of the class, and returns
it.

 The method new is de�ned on every class, and returns a new instance of the class.

Cool. Let’s have a look at that object:

p Calculator.new

The output will seem a little bit weird, and technical at �rst:

#<Calculator:0x007fb2fbe50910>

The format #<...> tells you that this object is not a simple thing like a number, string, or array.
Instead, it just tells you the name of the class, Calculator , and the internal id that Ruby has assigned
to this object.

Every object has its own, unique, internal object id, and when I ran this code on my computer, Ruby
assigned the id 0x007fb2fbe50910 . If you run it, you’ll get a di�erent one. In practice, most of the time,
you can simply ignore this id.

Also, we can check that our new calculator instance indeed is an instance of the class Calculator :

$ irb

> class Calculator

> end

> calculator = Calculator.new

> calculator.class

=> Calculator

> calculator.is_a?(Calculator)

=> true

64 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

De�ning instance methods


If you have read closely methods can be de�ned and called on objects (i.e. instances), e.g. 1.odd? .
And you have just seen that they can also be de�ned on classes, e.g. Calculator.new .

Fairly straightforward, methods that are available on classes are called class methods, and methods
that are available on instances are called instance methods.

In this chapter we want to add the “stand alone” methods that we’ve learned to port (move) in the
previous chapters Writing Methods to our class Calculator so that they’ll end up as instance
methods.

Here’s how we can do that.

class Calculator

def sum(number, other)

number + other

end

end

That’s right. You simply move the method into the class body, so that it’s enclosed by it.

 Instance methods are de�ned inside the class body.

Also note that the method de�nition is indented by one level, that is, 2 spaces. This signals that the
method sum belongs to the class Calculator . Everything between the line class Calculator and the
�nal line end is called the “class body”, and just like method bodies we indent them by one more
level.

 On formatting: the keywords class and end sit on the same level. The class body is
indented by one level.

Cool.

So, how can we use the new method? That is, how can we call the method sum on a calculator?

Before you read more, think about this a little. In theory you have all the bits and pieces to answer this
question:

You know how to create a new calculator instance (object).


You know how to call a method on an object.
You know how to pass arguments (extra bits of information) to the method call.

65 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

We can instantiate (“order”) a new instance from our Calculator class, and call the method sum on it
like so:

calculator = Calculator.new

puts calculator.sum(2, 3)

This will output 5 . Success :)

A calculator that cannot do anything but additions is pretty useless. Let’s spice our class up by adding
more operations, i.e. methods. Also, let’s rename sum to plus so it matches the operator:

class Calculator

def plus(number, other)

number + other

end

def minus(number, other)

number - other

end

def multiply(number, other)

number * other

end

def divide(number, other)

number / other

end

end

Now our calculator already is slightly more useful: We can do the most basic math operations with it.

calculator = Calculator.new

puts calculator.plus(2, 3)

puts calculator.minus(2, 3)

puts calculator.multiply(2, 3)

puts calculator.divide(2, 3)

This will output:

66 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

-1

Whoops!

This looks all good except for the last line, right. Remember why that is? Right, dividing one integer
number by another returns, again, an integer number. And these aren’t quite great for calculating
divisions.

One thing we could do about this is require the users of our calculator to pass (provide) the
appropriate types of numbers themselves. So it would be their own responsibility if something goes
wrong with the division.

However, we could also think that a calculator should be smart enough to notice this. So we could
improve our calculator to always change the type of the numbers passed to �oating point numbers as
part of the method divide . In other words, the method divide would take the numbers, makes sure
at least one of them is a Float (�oating point number), and only then do the calculation.

The method used to convert an integer to a �oat is to_f . When called on a �oat it will just return the
�oat:

$ irb

> 1.to_f

1.0

> 1.0.to_f

1.0

Alright, lets use that knowledge to improve our divide method. It will be su�cient to call the method
to_f on one of the numbers, because that will make sure we get a Float back:

class Calculator

# ...

def divide(number, other)

number.to_f / other

end

end

With that in place our calculator always returns a Float from the method divide :

67 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

calculator = Calculator.new

puts calculator.plus(2, 3)

puts calculator.minus(2, 3)

puts calculator.multiply(2, 3)

puts calculator.divide(2, 3)

This will output:

-1

0.666666666666

Perfect.

Let’s move on, and de�ne a class Person , which should be even more fun.

Initializing objects
In the moment of birth

Let’s start over, and de�ne a new class.

Remember how we said that objects can be thought of as two things: They know stu�, and they can
do things.

Let’s de�ne a class Person . People obviously also know things, and can do things.

Here’s how to de�ne a shiny, new, empty class Person :

class Person

end

Again, that’s not a very useful class, but we can instantiate it, and create an actual, concrete person
instance (object) from it:

p Person.new

Now, before we add any behaviour (methods) to our class, we want to be able to give it some initial
data: In our case, we want the person to know its own name.
68 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

We can do this like so:

class Person

def initialize(name)

end

end

You see that we add a method called initialize to the class, and this method accepts a single
argument, which is called name . At the moment, this method is still empty. We’ll add some code to it
in a bit.

The important bit to learn for you is: the method initialize is a special method with a special
meaning in Ruby:

Whenever you call the method new on a class, as in Person.new , the class will create a new instance of
itself. It will then, internally, call the method initialize on the new object. Doing so it will simply pass
all the arguments that you passed to new on to the method initialize .

So we can now create a new person instance by calling …

Person.new("Ada")

… and the string "Ada" will be passed on to our initialize method, and end up being assigned to
the local variable name .

 The special method initialize is called under the hood when the object has been created
by the class method new .

Obviously, our initialize method does not do anything with the String passed, yet. That’s right. We’ll
get to that in the next chapter.

To recap, when you call new on the class Person , and pass the string "Ada" then the method new will
create a new instance of the class, and call initialize on it, passing the same argument list, which in
our case is the single string "Ada" .

When we create a new instance of a class by the way of calling the method new on that class, we also
say that we “instantiate” that object: By calling Person.new we instantiate a new person object.

Instance variables
An object’s own knowledge

Now that you understand how the string that we pass to the method new ends up being passed to
69 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

the new object’s initialize method, we can start improving initialize , so it does something with
the string, and actually initializes our new object:

class Person

def initialize(name)

@name = name

end

end

This introduces another new concept: @name is a new type of variable, called an “instance variable”.

The body of the initialize method now does nothing else but assign the value of the local variable
name to an instance variable @name .

You remember how we said that each method has its own local scope, which is created when the
method is called, and populated with local variables from the arguments list. You have also learned
that this scope is erased, and thrown away when Ruby exits the method body and returns from the
method. And that local variables that are visible in one method are not visible in other methods: that’s
why they are called local.

Now, the thing is: Every object also has its own scope.

An object’s scope is populated with instance variables, in the moment we assign something to them.
And they are visible everywhere in the object, that is, in every method that the object has.

 Instance variables live in, and are visible everywhere in the object’s scope.

You can think of the object’s scope as your own knowledge, or memories.

For example, you know your name, your email address, and your email password. You keep this
knowledge around, and you can use it when you do things (such as responding to another person).
Likewise, an object keeps its instance variables around, as long as the object exists.

Ok, let’s see how that works in practise.

If you create, and output an instance of our class Person , you’ll see that Ruby now prints out the
instance variable, too:

person = Person.new("Ada")

p person

The �rst line creates a new instance of the class Person , passing the string "Ada" , and assign this new
object to the variable person . The second line will then print it out:

70 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

#<Person:0x007fd8947aa868 @name="Ada">

As you can see this includes the instance variable @name with the value "Ada" : This speci�c, concrete
instance of the class Person knows their name.

You can think of this as you, as a programmer, creating this new person, and in the moment of its
creation, its birth, you also give it a name. Which kind of how it works with real people, too, isn’t it?

Hmm, well … Yeah, sort of. Anyhow, let’s move on.

Attribute readers
Asking for information

Remember how we initially said that people have the ability to remember their name, and tell it, when
asked?

We’ve already implemented the �rst part of this. Our person instance now knows her name “Ada”.

Let’s look at the second part. You also remember that methods are either questions or commands.
We want to add a method that implements answering the question “What’s your name?”.

And it is as simple as this:

class Person

def initialize(name)

@name = name

end

def name

@name

end

end

Before we discuss what this does, let’s look at how we can use our new method. We can now call the
method on the person object, like this:

person = Person.new("Ada")

puts person.name

So this prints the name Ada , and that’s what we want: we can create a new person object, passing a
71 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

name to it. Once that person has been created we are able to ask for its name, and we’ll get the name
back.

How does this work, exactly, under the microscope?

Let’s walk through it, step by step:

On the �rst line, the object that ends up being assigned to the variable person is an initialized,
new instance of the class Person . By “intialized” we mean that the method initialize has
already been called, and it already has assigned the string "Ada" to the instance variable @name .

Now this person object has the method name , as de�ned in the class de�nition of Person above,
and in the second line we call this method: person.name .

When the method name is called, it does nothing else but evaluate the instance variable @name
from the object scope. Because this has previously been set to "Ada" it will return this string. And
because this is the last line in the method name the method also will return this string.

For that reason the method call person.name returns the string "Ada" , which is then passed to
puts , which prints it out.

Methods that do nothing else but return a value assigned to an instance variable with the same name
are very common.

In fact they are so common that there’s a word for them: they are called “attribute readers”. By
“attribute” the Ruby community means an instance variable, so an attribute reader is a method that
reads an instance variable.

 An attribute reader returns the value of an instance variable.

Another way of looking at this is that an attribute reader is a method that “exposes” an instance
variable. It makes it accessible for others. I.e. it allows you to ask for the value of an instance variable
with the same name, and does nothing but return its value. Once de�ned others can ask this object
for knowledge that otherwise would be private, and unaccessible.

In our case the attribute reader name exposes the instance variable @name , so others can ask for it.

 An attribute reader exposes an instance variable.

We don’t know why the community has chosen to use the term “attribute” here: It would be much less
confusing to use the term “instance variable reader” instead. Maybe the simple reason is that
programmers don’t like to type more than necessary, and this saves 8 characters. Who knows :)

Attribute writers
Setting information

72 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Imagine in our application a person not only needs a name, but also a password. However, let’s also
imagine that, at the time of the creation of a new person instance, this password is not yet known.
(Who would give a toddler an email password anyway?)

Instead we want to be able to tell the person object about its email password later.

We can do this like so:

class Person

def initialize(name)

@name = name

end

def name

@name

end

def password=(password)

@password = password

end

end

As you can see, the method password= does nothing else but take a single argument (called password )
and assign the value of this local variable to the instance variable @password .

This method’s structure looks exactly the same as the method initialize , doesn’t it? Execpt that
initialize is called whenever you call new on the class. Our new method password= needs to be
called on the object itself, once it has been created.

Again, because this kind of method is used so often, there’s another name for it: it’s an attribute
writer. (And again, we think it should have been called an “instance variable writer” instead.)

Now, we can use the attribute writer like so:

person = Person.new("Ada")

person.password=("super secret")

p person

If you execute this, then it will print out:

#<Person:0x007fb61c1edcf8 @name="Ada", @password="super secret">

73 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

So, yeah, we can see that, after calling person.password=("super secret") the object now has an
instance variable de�ned, i.e., the person now knows their password, too.

 An attribute writer allows setting an instance variable.

That method call looks a little odd though, doesn’t it?

Remember what we’ve said above about the syntax sugar that Ruby adds for the assignment operator
= ?

Exactly the same works for attribute writers, that is, methods that end with an equals sign = .

That’s right. So we can also write this instead:

person = Person.new("Ada")

person.password = "super secret"

And this reads just so much better, doesn’t it?

Just remember that, under the hood, when running your code, Ruby translates the line
person.password = "something" to person.password=("something") , and this simply calls the method
password= , passing the value on the right hand side as an argument: it’s just another method :)

We think this is pretty cool.

State and behaviour


Data and methods

Lets have another look our class de�nition for Person :

74 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Person

def initialize(name)

@name = name

end

def name

@name

end

def password=(password)

@password = password

end

end

Do you notice something?

Our class demonstrates an important thing about objects:

There’s a way to ask a person for their name , but no way to set a new name. On the other hand there’s
a way to set a new password to the person, but no way to ask for it.

If you think about it, that makes sense, doesn’t it?

If you join our Ruby beginners study group for the �rst time, and we ask you for your name, you’ll
happily tell it. But if we ask for your Gmail password, you will probably just laugh at us, or stare at us,
or show some other error message. ;) In any case, you won’t tell us your email password, because
that’s private information.

The same is also true for objects.

Every object has its own object scope that might hold a bunch of instance variables. These are private
to the object. Our person object knows their password, once it has been given to them. But from then
on, they won’t tell anyone the password, because there’s no method for that. On the other hand,
there’s a method name , which is an attribute reader, so we can ask our person object for their name.
But there’s no way for others to give a new name to the person, because there’s no method for that,
no attribute writer name= .

This concept is called encapsulation, and it is one of the main motivations behind the whole paradigm
of object-oriented programing:

We can say that an object encapsulates state (data, knowledge), which is private to the object, and
exposes behaviour by the way of having publicly accessible methods.

 Objects have state (instance variables) and behaviour (methods).

75 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

So, we have now created our �rst little class, and it’s one that you could actually see in real
applications.

Interacting Objects
We’re now able to create our own objects. However, they don’t do a whole lot, yet, right? Why not
create two people, and let them greet each other.

Let’s see.

Here’s what we’d like to achieve:

class Person

def initialize(name)

@name = name

end

def name

@name

end

end

person = Person.new("Anja")

friend = Person.new("Carla")

person.greet(friend)

We’d like this to print out the following for starters:

Hi Carla!

If we run the code above we’ll get an error message that tells us what to do next:

NoMethodError: undefined method `greet' for #<Person:0x007fbb5e9c88c8 @name="Anja">

Right, we need to de�ne a method greet . Let’s do that:

76 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Person

# methods from above ...

def greet

end

end

If we run this code, we’ll now get a new error message. Great, that’s progress:

ArgumentError: wrong number of arguments (1 for 0)

Right, how would one person greet another without knowing who that other person is? So we need to
make our method accept an argument:

class Person

# methods from above ...

def greet(other)

end

end

If we run this we won’t see an error message any more. Yay! However, it also does not print anything
so far - our method does not do anything, yet.

Alright, let’s add some actual behaviour, and print out “Hi!” for starters.

class Person

# methods from above ...

def greet(other)

puts "Hi!"

end

end

What happens when you run that? It works, right. This should output Hi! to the screen.

However, how can Anja greet Carla, speci�cally? How can any person greet any other person? Well,
the method knows the person to greet (she has been passed as an argument to the method) so she
can ask her for her name:
77 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Person

# methods from above ...

def greet(other)

puts "Hi " + other.name + "!"

end

end

Does this make sense?

Let’s have another look at the full code:

class Person

def initialize(name)

@name = name

end

def name

@name

end

def greet(other)

puts "Hi " + other.name + "!"

end

end

person = Person.new("Anja")

friend = Person.new("Carla")

person.greet(friend)

So we instantiate two Person objects, and assign them two variables person and friend . Then we
call the method greet on the �rst one (Anja), and pass the second one ( friend , which is Carla) as an
argument.

Now Ruby jumps into the method body of the method greet , and assigns the local variable name
other to the Person instance passed (i.e. Carla).

It then asks the Person instance other for their name (which will return the String "Carla" , and
concatenates it to (glues it together with) two other strings "Hi " and "!" . So this results in a new
String Hi Carla! which it then passes to puts .
78 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Ok, let’s spice that up a little, and let Anja add her own name to this String, too:

class Person

# methods from above ...

def greet(other)

puts "Hi " + other.name + "! My name is " + name + "."

end

end

Nice. This now outputs:

Hi Carla! My name is Anja.

Remember how you could call the method add_one from another method add_two before? The same
works here, too: We can call the person’s own method name by just using it, since this method is
de�ned on the same class, and thus every instance of Person . We’ll look at this a little more in the
next chapter.

For now let’s add another line at the end, and let Carla greet Anja back.

Again, here’s the full code:

79 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Person

def initialize(name)

@name = name

end

def name

@name

end

def greet(other)

puts "Hi " + other.name + "! My name is " + name + "."

end

end

person = Person.new("Anja")

friend = Person.new("Carla")

person.greet(friend)

friend.greet(person)

And this outputs:

Hi Carla! My name is Anja.

Hi Anja! My name is Carla.

What do you think?

Of course this is still quite a simplistic example. It already shows how you can “model” a certain “real-
world” concept in terms of Ruby code, instantiate it, and let it interact with another thing.

By the way if you’d like to see how to make the method greet more pretty, and a little bit easier to
read, check out the chapter on String interpolation.

Object Scope and Self


Remember how we said that when Ruby �nds a method call she then deviates from the normal
control �ow which goes from top to bottom? Instead she jumps into the method body.

We also said that this method body has its own scope, like a shiny, new room where local variables
from other scopes are not visible. Instead it has its own local variables, some of which might be
80 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

de�ned via the method’s arguments.

And we also said that inside any object’s method all instance variables of this object, and all other
methods of this object are also visible.

We also may have a look at that mysterious top-level object that Ruby enters when she starts
executing a program, or IRB.

We are now �nally ready to put all these things together a little more, and introduce a new keyword:
self .

The Object Scope


In fact, in Ruby, there are even more scopes than just the local method’s scope:

There’s the method’s local scope, which holds all local variables. And there’s the object’s scope which
holds all instance variables and method names.

When Ruby’s control �ow jumps into a method then both of these scopes are visible at the same time.
For any given name Ruby will �rst check the local scope, and then the object scope.

In reality this most importantly means that from any method on an object, you can access:

all local variables


all instance variables
all of the object’s methods

It also means that one can overwrite, sometimes accidentally, method names with variable names.
Remember they read just the same in Ruby? While this is a really cool feature, it also means we need
to be aware of it.

Consider this code:

class Person

# ...

def name

@name

end

def greet(other)

name = other.name

puts "Hi " + name + "! My name is " + name + "."

end

end

As you can see this de�nes a new local variable name . The code is very similar to what we had before,
81 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

except that we store the other person’s name to a local variable name �rst, and then use this variable
on the next line when we put together our String.

This breaks our code, of course, in the sense that we don’t get the expected greeting any more.
Instead it contains the same name twice:

Hi Carla! My name is Carla.

That is because, on the last line of the method greet , when Ruby looks at the word (identi�er) name
she �rst checks the local scope of the method, and �nds a local variable de�ned, so she uses it. Only if
there was no local variable de�ned she would check the object’s scope, and �nd the method with the
same name name , and call it.

 When she �nds an identi�er, Ruby looks for a local variable �rst, and then for a method.

Luckily, there’s a way to still access the object’s scope:

Self
Every object knows itself, in every method, by the way of calling self . This is a special keyword in
Ruby, that means just that: The object itself.

Let’s try that, and output self . In order to do that we need to add it somewhere inside the object.
Any method would be good for that, but let’s just use the initialize method:

class Person

def initialize(name)

@name = name

p self

end

end

person = Person.new("Anja")

p person

This should output something like this:

#<Person:0x007f9994972428 @name="Anja">

#<Person:0x007f9994972428 @name="Anja">

As you can see we output the same object twice. Once in the initialize method using p self , and
82 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

once in the outer scope using p person . You can also see that the cryptic looking object id is the same
for both instances. So we can know it’s indeed the very same object.

 Inside any method the object can be referred to using the keyword self .

So we can �x our code from above like this:

class Person

def name

@name

end

def greet(other)

name = other.name

puts "Hi " + name + "! My name is " + self.name + "."

end

end

Now we call the method name on two di�erent objects again. When Ruby sees self she knows that
we’re referring to the person object, and she calls the method name on it.

This �xes our greeting:

Hi Carla! My name is Anja.

Keywords
Why do we keep saying that self is a keyword? Well, because is not a method. It’s a “special thing” in
Ruby. For example this means that the following will raise an error:

person = Person.new("Anja")

p person.self

This raises the error:

NoMethodError: undefined method `self' for #<Person:0x007f9994972428 @name="Anja">

It’s not a method, it’s a special thing.

83 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Other keywords that also aren’t methods (or objects, or classes) are, for example, def , class , and
end . You’ll also learn about do , if , elsif and else a little later.

 Keywords are words that have a special meaning in Ruby, such as class , def , end , and
self .

Blocks
Like methods, but without a name

Blocks are one of the things programmers absolutely love about Ruby. They are an extremely
powerful feature that allows us to write very �exible code. At the same time they read very well, and
they are used all over the place.

So, what is a block?

A block, essentially, is the same thing as a method, except it does not have a name, and does not
belong to an object.

I.e. a block is an anonymous piece of code, it can accept input in form of arguments (if it needs any),
and it will return a value, but it does not have a name.

Moreover, blocks can only be created by the way of passing them to a method when the method is
called.

 A block is a piece of code that accepts arguments, and returns a value. A block is always
passed to a method call.

Let’s jump right in:

5.times do

puts "Oh, hello from inside a block!"

end

As you can see times is a method that is de�ned on numbers: 5.times calls the method times on
the number 5 .

Now, when this method is called the only thing passed is a block: that is the anonymous piece of code
between do and end . There are no objects passed as arguments to the method times , instead it just
passes a block.

The method times is implemented in such a way that it simply calls (executes) the block 5 times, and
thus, when you run the code, it will print out the message "Oh, hello from inside a block!" 5 times.

84 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

The code almost reads like an English sentence Five times do output this message, right? It does, and
that’s one of the reasons why Rubyists love using blocks.

One of the things that seem rather hard to grasp about blocks is that

First, they are anonymous chunks of code.


Second, they are passed to methods just like other objects.
And third, they still can be called (just like methods), from inside the method that it was passed to.

Does that make sense?

Imagine you are the object that represents the number 5 . You are a number and you do know your
own value.

Now I hand you a piece of paper saying: Please print the following on the screen: "Oh, hello!" ,
and I ask you to execute this instruction as many times as the value that you know.

You’d go ahead and follow the instructions on the paper, and thus print out the message. You repeat
this 5 times, because 5 is the value that you know.

This is pretty much how the method times on numbers works, and how blocks work: times takes the
block (the instructions), and runs it as many times as the value of the number.

To summarize: Methods can not only accept input in the form of objects passed as arguments. They
can also accept this one special piece of input, which is an anonymous block of code. And they can
then call (execute) this block of code in order to do useful things with it.

Let’s look at some other aspects of how blocks work next.

Alternative block syntaxes


Next to the syntax shown before, using do and end , Ruby comes with an alternative syntax, which
uses curly braces for de�ning a block.

These two statements do exactly the same:

5.times do

puts "Oh, hello!"

end

5.times { puts "hello!" }

Both statements de�ne a block, which is passed to the method times . And both blocks contain a
single line of code.

85 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

 Blocks can be de�ned enclosing code in do and end , or curly braces {} .

So, when do you use one or the other syntax?

In the Ruby community there’s the convention to use curly braces if you have a single line block and it
�ts nicely on the same line (as, in our example, it does).

Whenever you need to have more than one line in your block, then you use the syntax using do and
end . Sometimes people also use the do and end syntax when they feel it makes the code more
readable.

 Use curly braces {} for blocks, when the code �ts on one line.

Block arguments
Blocks make a lot of sense on methods that are de�ned on collections like arrays and hashes.

Let’s have a look at some examples with arrays.

In our previous example that used the method times our block did not accept an argument. A block
that accepts an argument looks like this:

[1, 2, 3, 4, 5].each do |number|

puts "#{number} was passed to the block"

end

And, again, this is the same as:

[1, 2, 3, 4, 5].each { |number| puts "#{number} was passed to the block" }

It is unknown to us why Matz has chosen to not enclose the argument list of a block with round
parentheses just like method argument lists. Instead, Ruby wants us to use vertical bars (we call them
“pipes”).

So, for blocks, do |number| is the same that is def add_two (number) for a method de�nition, except
that the method wants a name while a block is anonymous: |number| and (number) both are
argument lists. The �rst one is used for blocks, the second one for methods.

 Block arguments are listed between pipes | , instead of parentheses.

Now, when you run the code example above, you’ll see the message printed out for each of the
86 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

numbers contained in the array.

Does that make sense? Again, our code almost reads like an English sentence:

With this array for each of its elements, naming it number , output the following message.

The method each is de�ned on arrays, and it does just this:

It takes each of the elements in the array and calls the block, passing the element as an argument.
The block can then do whatever you want it to do with the element. In our case we interpolate it into a
string and print it out to the screen.

Block return values


Remember that we said a block returns a value just like methods do? So far, in our two examples
above, we did not do anything with the return values of the block.

Here’s an example that does that:

p [1, 2, 3, 4, 5].collect { |number| number + 1 }

This will take the array of numbers, and transform it into another array.

It does this by calling the method collect on the original array, which calls the given block for each of
the elements, and collects each of the return values returned by the block. The resulting array is then
returned by the method collect , and printed to the screen.

In other words, the method collect uses the block as a transformer. It takes each element of the
array, passes it to the block in order to transform it to something else, and then keeps all the
transformed values in a new array that the method collect then eventually returns.

Note that the method collect has an alias, which is map . These are exactly the same methods. Many
programmers prefer map over collect because it is shorter, and also more commonly used in other
languages. However, in our study groups we use collect more often, because it simply expresses
more clearly what the method does.

 Use the method collect to transform an array into another array.

Here’s another example that uses the return value of the block, can you guess what it does?

p [1, 2, 3, 4, 5].select { |number| number.odd? }

In this case, the method select uses the block in a di�erent way: as a �lter, or criterion, to select
values out of the array, and then return a new array with the selected values.
87 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Let’s walk through this step by step, under the microscope:

We create an array [1, 2, 3, 4, 5] .


We then call the method select on it, and pass our block as a �lter criterion.
Now, the method select calls our block for each of the numbers.
It �rst calls the block passing the number 1 .
We now are inside the block, and a local variable number is assigned the object that was passed
as an argument, which is the number 1 .
Inside our block we now call the method odd? on this number, and of course, because 1 is odd,
this will return true .
Since this is the only, and thus, last statement in the body of our block, our block also returns
true to the method select . select therefore will keep (“select”) the number 1 .
It then calls the block again, this time passing the number 2 . Of course, because this is not an
odd number, the method odd? and therfore our block will return false back the the method
select . Therefore it discards this element.
It keeps doing this for each of the remaining elements in the array, and eventually has this array:
[1, 3, 5]
The method select then returns this array and Ruby will pass it to the method p , which prints
the array out to the screen.

Thus, the code above prints out [1, 3, 5] .

 Use the method select to select a new array with values that match a criteria de�ned by
the block.

Here’s another example of a method that uses the block as a criterion:

p [1, 2, 3, 4, 5].detect { |number| number.even? }

Again, detect will pass each of the elements of the array to the block, one by one, and check the
return value of the block. However, as soon as the block returns something truthy (something that is
“equivalent to true”), the method detect will return the current object itself. Therefore, this will print
out 2 : the �rst number in the array that is even.

Inversion of control
In Ruby there are a lot more methods that accept blocks, and they do very di�erent things. However,
they have one thing in common:

By accepting a block, from you as a programmer, the method can pass control to you.

This design is an example for the principle of inversion of control, and it’s the real reason why
Rubyists love blocks so much.

88 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

What does that mean?

In short it means that Matz, the creator of Ruby, put a tool in place that can be used to allow methods
to pass control to its users (i.e. you as a programmer).

“Control” in this context refers to the question who gets to decide how things work.

In older languages, where there was no such tool, people either had to implement lots of very speci�c
methods, and guess what users might need in the future. Or they’d decide to just not implement any
of these methods at all.

For example, in Ruby, we don’t have to de�ne lots of methods like select_odd , select_even ,
select_lesser_than , select_greater_than and so on, … where each of these methods would be useful
for one very speci�c usecase.

Instead, the class Array only has to implement one single, very generic method for arrays: select .
Since Ruby has blocks, the method can allow you (as a programmer) to specify the criterion yourself:
by passing a piece of code, in the form of block to the method.

That way Ruby lets you, as a programmer, take over control, and specify what is used as a criterion to
select elements.

One of the reasons we mention this is because we think this is a nice example of a pretty abstract
principle applied to software design. There are lots of other principles like these, and they’ll make
more and more sense to you over time. Programming languages and code, from this perspective, is a
subject of design, and thus art, as well as social and cultural questions … much rather than strictly
logical or technical ones.

Iterators
Methods on arrays and hashes that take a block are also called iterators.

We say they iterate over the array, meaning that these methods take each element of the array and
do something with it.

In Ruby iterators are “chainable”, adding functionality on top of each other.

That means that, if you do not pass a block to an iterator method, such as each , collect , select ,
then you’ll get an iterator object back. You can then call more methods on these iterator objects, and
�nally pass a block. Like so:

numbers = [1, 2, 3, 4, 5].collect.with_index do |number, index|

number + index

end

p numbers

89 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This will print out:

[1, 3, 5, 7, 9]

What’s going on here?

The method with_index can be called on any iterator object. All it does is pass the index of the
element within the array to the block, as a second block argument, in addition to the element itself.

Inside of the block we can then use it, and add the index to the number itself.

So for the �rst iteration it will call the block with 1 and 0 , since 0 is the �rst “position”, that is, index.
It therefore returns 1 . For the second iteration it calls the block with 2 and 1 , and returns 3 , and so
on.

Therefore the method call eventually returns the array [1, 3, 5, 7, 9] .

 Iterators in Ruby are chainable.

Conditionals
If this is true, then do that. Otherwise do something else.

Often we want to check for a certain condition, and then based on it, do either one thing or another.
Or we want to do something only if a condition is true.

All practical programming languages have some way of expressing this, and in Ruby it looks like so:

number = 5

if number.between?(1, 10)

puts "The number is between 1 and 10"

elsif number.between?(11, 20)

puts "The number is between 11 and 20"

else

puts "The number is bigger than 20"

end

You can probably guess what it does, and how it works, can’t you?

Let’s walk through it one by one:

90 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

If you run this code it will print out The number is between 1 and 10 , because the number
assigned to the variable number on the �rst line is 5 , and for this number the method call
number.between?(1, 10) returns true . Ruby will therefore execute the code in the if branch:
The if branch is the block of code that comes after the line with the if statement, and that is
indented by two spaces. Once it is done executing the if branch Ruby will simply ignore the rest
of the statement.

If you change the number 5 on the �rst line to 15 , and run the code again, then it will print out
The number is between 11 and 20 . In this case Ruby will, again, �rst check the �rst condition
number.between?(1, 10) , but this time this method call returns false . Therefore, Ruby will ignore
the if branch, and check the next condition on the elsif line: number.between?(11, 20) . Now,
this method call returns true, because 5 is between 11 and 20 . Ruby will therefore execute the
elsif branch, and print out this message. Again, once it is done executing the elsif branch
Ruby will ignore the rest of the statement.

If you now change the number 15 to 25 , and run the code again, then it will print out The number
is bigger than 20 . Again, Ruby will �rst check the �rst condition, and �nd it returns false . It will
check the second condition, which now also returns false . Therefore Ruby will then execute the
else branch, and print out that message.

The elsif and else statements and branches are optional: you don’t need to have them. You can
have an if statement without elsif or else branches, an if statement only with an else , or you
could have an if statement with one or more elsif statements. Or combine all of them together:

There must be an if statement and branch.


There can be many elsif statements and branches.
There can be one else statement and branch.

Nothingness and the truth


Now is a good time to talk about the concepts of nothingness and truth in Ruby.

Nil

We have brie�y mentioned that in Ruby there is an object that represents “nothing”: the object nil .

That’s right. “Nothing” is a thing in Ruby (as well as in many other languages), albeit a very special one.
We could ramble on the philosophical implications of this, but instead we’ll just look at how this is
used in practice:

Remember how we can receive a value associated with a key from a hash?

dictionary = { :one => "eins", :two => "zwei", :three => "drei" }

p dictionary[:one]

91 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This will print out "eins" . However, what happens if we try to receive the value for a key that has not
been de�ned on the hash?

dictionary = { :one => "eins", :two => "zwei", :three => "drei" }

p dictionary[:four]

This will print out nil . Remember that every method call always will return some value? In cases
where there’s nothing to return, it will return nil , which represents nothing :)

In Ruby, nil , nothing, is something else than, for example, 0 , which represents something. An empty
string "" , an empty array [] , or empty Hash {} also all represent something. So they’re not nil .

True and false

We have also discussed that in order to represent truth, and the opposite of it, Ruby also knows the
values true and false .

You have seen them when we tried some of the methods on numbers, strings and arrays, like 3.odd? ,
"a string".start_with?("a") , or [1, 2, 3].include?(2) .

These so called predicate methods always return either true or false .

 Predicate methods end with a question mark, and return true or false .

The objects nil , true , and false also have classes, and you can check that in IRB yourself:
nil.class , true.class and false.class .

For a reason that we don’t know Matz (the creator of Ruby) has decided to call these classes NilClass ,
TrueClass and FalseClass , instead of just Nil , True and False . If you ever meet him at a
conference you can ask him :)

Truthiness and falsiness

Now, when we talked about if statements we used methods that actually return true and false
values, like the odd? method on numbers does. Comparison operators like == , < and > also return
true and false , as in:

number = 3

if number >= 5

puts "The number #{number} is greater than 5, or equal to 5"

else

puts "The number #{number} is less than 5"

end

92 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

However, what happens when we use methods as conditions that do not return true or false , but
something else, for example a string, number, or nil ?

For example, consider the following:

dictionary = { :one => "eins", :two => "zwei", :three => "drei" }

key = :four

if dictionary[key]

puts "The dictionary defines a value for the key #{key}."

else

puts "The dictionary does not define a value for the key #{key}."

end

As we saw before dictionary[:four] will return nil because this key is not de�ned. Is nil
equivalent to true or false ? Or will this raise an error?

If you run the code above then you see that Ruby will execute the else branch. That means Ruby
actually considers nil to be equivalent to not true , that is, false .

Now, lets use a key that actually is de�ned:

dictionary = { :one => "eins", :two => "zwei", :three => "drei" }

key = :one

if dictionary[key]

puts "The dictionary defines a value for the key #{key}."

else

puts "The dictionary does not define a value for the key #{key}."

end

As you saw before dictionary[:one] will return "eins" , because that’s the value associated with the
key :one . Again, do you think "eins" is equivalent to true or false ? Or will this raise an error
instead?

If you run the code then you’ll see that Ruby now executes the if branch, and considers the
condition (i.e. the string "eins" ) to be equivalent to true .

Think about this for second: Ruby considers everything to be equivalent to true that is not false or
nil . Or put the other way around, Ruby only considers nil to be equivalent to false .

Because “is equivalent to true” or “is equivalent to false” is quite a clunky thing to repeat so often the
programming community has come up with terms for this: truthiness and falsiness. So we can say

93 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

that the string "eins" is truthy. And nil is the only other thing that is falsy in Ruby, except false
itself.

To sum this up, if and unless look at the truthiness of a the value that is returned by the condition.
Everything except false and nil is truthy, including strings, numbers, arrays, hashes, and every
other object.

This also includes the number 0 , empty strings "" , arrays [] and hashes {} . These aren’t nothing
( nil ), instead they’re something, and therefore, in Ruby, truthy.

Here’s a pattern that you might see used when you look at other people’s code:

dictionary = { :one => "eins", :two => "zwei", :three => "drei" }

key = :one

translation = dictionary[key]

if translation

puts "The translation for #{key} is: #{translation}."

else

puts "The dictionary does not define a translation for the key #{key}."

end

If you read this out loud, does it make sense to you?

The code �rst looks up the translation from the dictionary hash. And then it says If there’s a
translation, then use it. Otherwise do something else.

Ruby’s concept of truthiness allows us to write our code in this concise way that almost reads like
English. And that’s one reason why many people love Ruby so much.

Operators
We’ve already used some arithmetic operators ( + and * ) above. You have also learned that
operators, under the hood, are just methods. Ruby just adds a little bit of syntax sugar on top of these
methods, so they’re sweeter to read, and write.

There also are operators for comparing things, for logical calculations, and other operations. Let talk
about some more of them.

Arithmetical operators
For numbers, the operators + and * obviously mean the mathematical operations of adding and

94 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

multiplying two numbers. Of course there are other arithmetical operators. Here’s a full list:

+ - addition
- - subtraction
* - multiplication
/ - division
** - exponentiation
% - modulus (the rest of a division, e.g. 5 % 2 returns 1 )

However, some of these methods are also de�ned on other objects, like strings and arrays.

Try it yourself in IRB:

$ irb

> "<3" + "!"

=> "<3!"

> "<3" * 3

=> "<3<3<3"

As you can see, these operators mean something di�erent for strings. But they also make sense, don’t
they?

Adding one string to another just means that they will be concatenated into one longer string. And
multiplying a string by a number means repeating it as many times.

The same works for arrays:

$ irb

> [1, 2] + [3, 4]

=> [1, 2, 3, 4]

> [1, 2] * 3

=> [1, 2, 1, 2, 1, 2]

Again, adding two arrays means combining them into one big array. And multiplying an array with a
number means getting a big array with the original elements repeated.

Logical operators
Logical operators are also, maybe more commonly, called boolean operators.

95 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

The term “boolean” originates from the book “The Mathemetical Analysis of Logic” written by George
Boole in 1847. Boolean logic has been fundamental in the development of computers, and
programming, since at their core, computers are all about processing whether or not there is current
�ow: on vs o� (true vs false).

If you are curious, feel encouraged to google and read up on this online, but for now, we can simply
look at the 3 fundamental boolean operators and what they do: and , or , and not .

The operator and returns true if, and only if, both values also are true . So, only the expression true
and true is also true . All of the expressions true and false , false and true , false and false
evaluate to false .

If you think about this, and come up with English sentences, then this will make a lot of sense: At the
restaurant I’ll have a tomato soup IF it is vegan AND they still have some.

The operator or on the other hand returns true if at least one of the values is true . So, only if both
values are false , the operator returns false .

That’s why it is logically correct to answer the question Would you like tea or co�ee for breakfeast?
with Yes, please. IF you’d like either tea, or co�ee, or both. You’d only say Hell, no! if you’d like an
orange juice instead :)

The operator not simply returns the negated, opposite value. not true returns false , and not
false returns true . Therefore, the following lines of code are the same:

puts "Always true" if not false

puts "Always true" unless false

Each of these three operators comes in two versions:

and and &&


or and ||
not and !

The di�erence between them has to do with what is called “operator precedence”.

From math you know that 1 + 2 * 3 evaluates to 7 , not 9 . This is because the multiplication *
operator binds stronger, and precedes the addition operator + . In other words 1 + 2 * 3 is same as
1 + (2 * 3) , and not the same as (1 + 2) * 3 .

In Ruby, the operators && , || , and ! bind stronger than, and thus precede their fellows and , or ,
and not .

Comparison operators
In order to compare things Ruby has a bunch of comparison operators.

96 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

The operator == returns true if both objects can be considered the same. For example 1 == 1 * 1
will return true , because the numbers on both sides represent the same value. The expression "A"
== "A" also returns true because both strings have the same value.

Likewise, two arrays are equivalent when they contain the same elements, in the same order. For
example [1, 2] == [1, 2] will return true , but [1, 2] == [2, 3] and [1, 2] == [2, 1] both will
return false .

Note that we say “considered the same” and “equivalent” because technically the two objects do not
have to be (and most often, as in our examples) are not the same objects. E.g. while evaluating the
expression "A" == "A" Ruby will actually create two di�erent string objects which both contain a
single character A .

In practice this is almost always what you want. For the rare case when you actually need to check if
two objects are the same object there’s the method equal? . E.g., "A".equal?("A") returns false .

Other comparison operators are: less than < , less than or equal <= , greater than > , and greater
than or equal >= . They also work on numbers and strings, in the way you’ll expect it. Open IRB and try
a few combinations on numbers and strings.

Comparison operators most often are used in order to formulate conditions in if statements. Like
so:

number = 20

puts "#{number} is greater than 10." if number > 10

The most funny operator in Ruby is <=> , because it’s called the spaceship operator. No kidding :) It is
rather rarely used, and it is useful for implementing custom ways of sorting things.

Operators are methods


As you have seen a number has methods named like the arithmetic operators + , - , * , and / . That’s
right! Interesting.

If you think about this, it makes sense: If everything is an object then numbers are objects. If “doing
things” means operating with methods by the way of calling them, then what would + be? A method
of course.

But if we call methods on objects using that dot . notation, then where are the dots in 2 + 3 * 4 ?

The trick is: Ruby adds them for you, silently. If you write the following code:

number = 2 + 3 * 4

97 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Then Ruby will translate this to the following:

number = 2.+(3.*(4))

Fun, isn’t it? These operators are all methods on numbers, and they can be called just like any other
method. (The same is true for lots of other operators, as you can see in IRB, when you run
1.methods.sort .) The code above is valid Ruby code, and both lines do exactly the same.

Ruby just adds a little bit of syntax in order to make it easier to read and write for us: It allows us to
write number = 2 + 3 * 4 instead of number = 2.+(3.*(4)) , which is a pretty nasty thing to type.

This is something called “syntax sugar”, because it makes the language more sweet (no kidding).

By the way, this works the same way for other things too.

For example, you have learned about the array and hash syntax that uses square brackets [] for
reading and writing.

Ruby translates this code:

array = [1, 2, 3]

array[3] = 4

puts array[3]

hash = { :one => 'eins', :two => 'zwei' }

hash[:three] = 'drei'

puts hash[:three]

to these method calls:

array = [1, 2, 3]

array.[]=(3, 4)

puts(array.[](3))

hash = { :one => 'eins', :two => 'zwei' }

hash.[]=(:three, 'drei')

puts(hash.[](:three))

Knowing this can be useful when you want to write classes that look and feel similar to arrays or
hashes, but behave di�erently.

98 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Bonus Chapters

String interpolation
As mentioned above you can stick strings together by using the + operator.

Consider the following code:

name = "Ada"

puts "Hello, " + name + "!"

This, of course, will output the message Hello, Ada! .

Glueing strings together like this works, and you can do it. However, there is another method of
accomplishing the same, and it is widely used, and usually preferred over concatenating strings with
+ .

This method is called “string interpolation”, and this is how it looks:

name = "Ada"

puts "Hello, #{name}!"

Using this syntax everything between the opening #{ and closing } bits is evaluated as Ruby code,
and the result of this evaluation will be embedded into the string surrounding it.

In other words, when Ruby �nds #{name} in this string, then it will evaluate the piece of Ruby code
name . It �nds that this is a variable, so it returns the value of the variable, which is the string "Ada" . So
it embeds it into the surrounding string "Hello, #{name}!" , by replacing #{name} .

Now we can also �nally explain the di�erence between strings created with single and double quotes:

String interpolation only works with double quotes.

That means that:

puts "Interpolation works in double quoted strings: #{1 + 2}."

puts 'And it does not work in single quoted strings: #{1 + 2}.'

will print out:

99 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Interpolation works in double quoted strings: 3.

And it does not work in single quoted strings: #{1 + 2}.

If you type the code above in your editor, and syntax highlighting for Ruby code is used, it should
highlight the code in the double quoted string, so it gives you a visual clue about the interpolation.

So, why do people prefer string interpolation?

First of all, again, it’s slightly fewer letters to type. In our example, that’s just 5 characters, no big deal.
However, consider a longer string, which is constructed using three, four, or more variables. Now this
extra space quickly adds up, and things wouldn’t �t nicely on a single line anymore.

Also, many people �nd that the syntax reads a bit better. There’s a little bit less clutter, making it a
little bit easier to see what’s going on.

One other, albeit pretty negligible reason is, that string interpolation actually uses less resources:

The code "Hello, #{name}!" creates one single new string object, and then embeds the existing
string "Ada" into it.

The code "Hello, " + name + "!" on the other hand creates 3 new string objects: �rst it creates
the string "!" , and passes it to the method + on the existing string "Ada" . The operator +
returns a new string, which now is "Ada!" . Now this string is passed to the method + on "Hello,
" , which again, creates a new string, "Hello, Ada!" .

So, string concatenation creates 2 more string objects even in our simple example. These
intermediate objects are immediately discarded, because they’re not used any more. We’re only
interested in the �nal result "Hello, Ada!" .

We recommend you get used to using string interpolation, just because this is what most developers
use.

Escape sequences

There’s one other little di�erence between single and double-quoted string that we should mention
while we’re at it.

In programming, strings can not only contain text as we normally think about it. They can also contain
control characters (http://www.wikiwand.com/en/Control_character). Control characters are also called
“non-printing” characters, even though they can have visual e�ects.

Control characters can represent all sorts of things, such as removing the last character (“backspace”),
the next one (“delete”), or even causing an auditable alert (“bell”).

The one most typically used in Ruby programs is the “newline” character.

Because there’s no way to represent a “newline” character using any of the keys on your keyboard
programmers have come up with the idea of escape sequences (http://www.wikiwand.com
/en/Escape_sequences_in_C): An escape sequence is a code that consists of a backslash and another

100 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

character, and this combination is used in place of control characters.

For example, \n is the escape sequence that stands for the “newline” character.

So this code:

puts "one\ntwo\nthree"

Will print out:

one

two

three

Now, escape sequences also only work in double quoted strings. If you try to use them in a single
quoted string like so:

puts 'one\ntwo\nthree'

then that will print out the string literally:

one\ntwo\nthree

Which means that escape sequences are not replaced in single quoted strings.

Top-level object
So, we’ve learned that objects come with lots of methods attached to them. And we’ve seen how we
can use them to do interesting things with the object, by the way of calling these methods.

Now, if you pop into irb , or if you write the following code into an otherwise empty Ruby �le, this
works:

$ irb

> is_a?(Object)

true

> methods

[:to_s, :inspect, ... ]

101 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

So, as you can see we can use some methods in Ruby without even de�ning an object at all: They’re
already there. And the method is_a? tells us that this already is an object … whatever “this” is.

What’s up with that?

This is something that pretty much blows some people’s minds, confuses the heck out of others, while
yet others don’t even notice or think about it at all. It is also something, that, when you ask around on
your local Ruby meetup, very few people can explain in a satisfying, and clear way. And neither do we,
yet.

Let’s still try.

Whenever you open IRB and it presents that prompt to you, or when you create a new, empty Ruby
�le … Ruby will not only execute your code: Before she does she �rst creates an empty, anonymous
Object, and kind of places you inside of it.

This empty Object kind of seems invisible, and it seems that those methods that we can de�ne in this
scope (space) were somehow “standing alone”. In fact they aren’t. They’re de�ned on this empty,
anonymous Object that we usually don’t see.

This Object often is referred to as the top-level scope in Ruby.

 The top-level scope is an empty, anonymous object. All Ruby code starts in here.

Confusing? Yeah. Don’t worry. This is something many Ruby programmers do and use everyday
without ever asking the question why it works, exactly.

Hopefully some of this will become more clear once you’ve written your own methods and classes.

Lots of other methods


If you look at the methods that are de�ned on strings and arrays (e.g. run [].methods.sort or
{}.methods.sort in IRB), then you’ll �nd quite a bunch of method names that look like they are doing
exactly what their names describe.

For example, some of the things you can do with strings are:

"a string".capitalize returns "A string" , with the �rst letter uppercased.
"a string".length returns 8 , which is the length of the string.
"a string".start_with?("a") returns true , because the string starts with an "a" .
"a string".include?("s") returns true , because the string contains the character "s" .

Some examples for useful methods on arrays are:

102 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

[5, 1, 3].sort returns another array, with the elements sorted: [1, 3, 5] .
[5, 1, 3].size returns 3 , the number of elements in the array.
[1, 1, 1, 2].uniq returns a new array with duplicate elements removed: [1, 2] .
[1, 2, 3].join(", ") returns a string "1, 2, 3" .
[1, 2, 3].include?(2) returns true because the array contains the number 2 .

How do you �nd all these methods?

The quickest way to �nd a certain method for an object often is to just ask Google: “ruby array sort”.
That will point you to the Ruby documentation. Another way is to read through all the methods for the
class on the respective Ruby documentation page. And of course, you can also read through the
method names returned by [1, 2, 3].methods.sort .

Questions and commands


Generally speaking, methods play one of two roles: They either answer a question, or they perform a
command.

For example, if we have a user object, and users have a name, then we would ask the user object for
its name by calling the method name : user.name would return the user’s name. Arrays know their size
(how many elements they have), so we can ask an array: [1, 2, 3].size will return 3 .

Another example is the method sort on arrays. This method does not actually sort the array that it is
called on. Instead it returns a new array with the same values, but in a sorted order:

array = [3, 2, 1]

p array.sort

p array

This will output [1, 2, 3] and then [3, 2, 1] . So we see that the original array is still the same.

Often questions need another bit of information passed. E.g., we can ask a string Do you start with
this character?, and we’ll need to pass the character that we are talking about: "a
string".start_with?("a") . The answer to this question will be true . Or if we ask an array if it includes
a certain element, then of course we need to pass that element, as in [1, 2, 3].include?(1)

The other role that a method can play is being responsible for executing a certain command.

For example in Rails objects that can be stored to the database have a method save . Of course, the
purpose of this method is to save the object to the database. E.g. user.save would save some
changes that we’ve made to the user before, like, maybe we have given them a new password.

Another example is the method sort! on arrays. Di�erent from the method sort (without an
exclamation mark), this method tells the array to sort itself:

103 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

array = [3, 2, 1]

array.sort!

p array

If you run this code, then it will print out [1, 2, 3] : the array is now sorted.

Another example for a method that is a command is the method puts . All it does is print something
to the screen, and it always returns nil .

Whenever you think about adding a new method to your code it makes sense to think about the role
the method should have. Is it a question? Or a command?

Alternative Syntax
You have, so far, learned that Strings are de�ned using single or double quotes, like so:

"A String"

'Another String'

And Arrays are de�ned using square brackes, with a comma separated list of objects, like so:

["One", "Two", "Three"]

We’d like to quickly mention two alternative syntaxes for de�ning the same objects, even though
they’re not used very often. However, you may sometimes �nd them in other people’s code, so it’s
useful to know they exist.

Strings
First, Ruby has an alternative syntax for de�ning strings that goes like so:

%[any-character]The actual string[the same character]

Meaning, that when there’s a percentage character % followed by any other character, which also
closes the whole thing, then this de�nes a string, too.

For examples these de�nitions all mean exactly the same:

104 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

"A String"

'A String'

%(A String)

%{A String}

%|A String|

Which character is used to open and close the string is a matter of style, and preference. The author
of this text prefers round paratheses for readability, but others prefer curly braces or pipes. There’s
no very clear convention in the Ruby community.

When would you use this alternative syntax?

Sometimes you need to de�ne a string that itself contains (or may contain, in future versions) the
same quote character that you’ve used to de�ne the string. For example, if you have a string that
contains the string "Name" , including the quotes, but in the same string you’d also like to use String
interpolation, so you’d normally use double quotes to de�ne the string. In that case you’d need to
escape the double quotes that are contained in your string.

It probably helps to look at an example. Imagine you’re working on an application that asks the user
for an email address, validates the format of the given address, and then displays an error message if
the format looks invalid:

The given email address "ruby@monstas" does not look like a valid email address.

Using double quotes your code might look like this:

address = "ruby@monstas"

message = "The given email address \"#{address}\" does not look like a valid email address."

puts message

Try running this code, and then also try removing the backslashes, and running it again. You’ll get a
syntax error message because Ruby thinks the second double quote (after address ) closes the �rst
one, so it would look at #{...} outside of a string, which is not valid Ruby.

While the above code, including the backslash characters, is valid Ruby code, it looks a little ugly.
Typing this stu� is kinda cumbersome, and programmers usually hate it.

So Ruby gives us another, nicer way to express the same:

message = %(The given email address "#{address}" does not look like a valid email address.)

Also, this allows us to freely change the message later, without having to change the quotes. For
105 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

example, if our original message would have looked like so:

message = %(The given email address does not look like a valid email address.)

We could now change it to say the following without changing the quotes:

message = %(The given email address doesn't look like a valid email address.)

Arrays
Imagine you are running a programming study group, and you want to quickly write a piece of code
that runs a little ra�e to assign people to pairs randomly.

people = [

"Anne",

"Elizabeth",

"Erica",

"Iryna",

"Johanna",

"Juliane",

"Katja",

"Katrin",

"Maria",

"Renate",

"Sureka",

"Miriam",

"Zazie",

"Anja"

people.shuffle.each_slice(2) do |pair|

puts pair.join(', ')

end

Well, this code works. But wouldn’t it be cool to be able to de�ne the array without having to write out
all those quotes and commas? They’re quite cumbersome to type, aren’t they? Also, if we could omit
them then we could just copy and paste that list of names from some where else, without modifying it
further.

Luckily, Ruby provides us with a piece of syntax that does exactly this:

106 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

people = %w(

Anne

Elizabeth

Erica

Iryna

Johanna

Juliane

Katja

Katrin

Maria

Renate

Sureka

Miriam

Zazie

Anja

people.shuffle.each_slice(2) do |pair|

puts pair.join(', ')

end

The w in %w(...) stands for “words”, which means an array de�ned like this will always only contain
strings. So, %w(1 2 3 4) would result in the same array as ["1", "2", "3", "4"] .

Using the right words


Naming things is hard

Just like programmers are obsessed about formatting, they also care a lot about how to name the
things they create.

Choosing good names for your variables, methods, and classes is important, because this makes your
code more expressive and easy to read. In fact, once you’ve learned the basic concepts of Ruby, well
crafted code will read almost like a prose text to you. Not necessarily like your favorite novel, but
maybe like a recipe or other instructional prose. Ruby is particularly great for writing expressive,
readable code.

Here are a few examples of great, and rather bad names to pick.

Consider this code:

107 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Email

def initialize(str, string2, headers_hash)

# ...

end

# more methods ...

end

an_email = Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" })

From looking at the �rst two lines of this code you can �gure out that the author de�nes an Email
class, and it takes 3 arguments, two of which probably are supposed to be strings, and one is a hash
containing some headers.

But what’s the purpose of the �rst two arguments? All we know the author wants them to be strings.
So we might have to consult the documentation, or look at examples using the class. Luckily we can
�nd an example at the very bottom of the �le, and see that the �rst argument is supposed to be the
subject, while the second one is a date.

Using the “type” of an object as a variable name, or part of a variable name, usually is not a very good
idea: string , array , hash often are bad names, except in contexts where the type of the object is all
that matters. One example for such a context is the method de�nition def encrypt(string) in the
Modules chapter.

In our case it makes sense to name these arguments subject and date in the �rst place, in order to
make it easier for others to understand the purpose of these arguments:

When you tell your non-programmer friends that “An email requires two strings and a hash of
headers.”, they’d probably stare at you weird and switch to another topic. When you instead say “An
email requires a subject, a date, and some headers” then they might roughly understand what you’re
saying.

So let’s rename them:

class Email

def initialize(subject, date, headers)

# ...

end

end

email = Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" })

Also, the �rst argument name str in the �rst example is an abbreviation, which is something that
108 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

isn’t very common in the Ruby world. People used to use abbreviated variable names back when
memory was extremely sparse, and expensive: longer variable names would consume more memory.
Nowadays there’s just no reason any more to make your fellow developers puzzle over abbreviated
names. Consider var , var1 , var_2 bad names, and instead use names that reveal (talk about) your
intentions, and their purpose.

Did you notice the local variable name an_email in the �rst example? The name email in the second
example also is much better in most situations. The pre�x an_ doesn’t add any kind of information.
It’s just noisy, and adds clutter.

Another example:

emailslist = [

Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" }),

Email.new("Keep on coding! :)", "2015-01-03", { :from => "Dajana" })

emailslist.each do |mail|

puts mail.subject

end

Again, list says something about the type. Why not just call it emails . The plural already says that
it’s some kind of list.

Also, the block argument mail deviates from the class name Email , and the variable name emails …
and thus might raise a question “Wait, is this a mail maybe something di�erent from an email in this
code?”. So why not avoid confusion like that in the �rst place and call it email … simply the singular
form of the name of the collection emails :

emails = [

Email.new("Hi there, Ruby Monstas!", "2015-01-02", { :from => "Ferdous" }),

Email.new("Keep on coding! :)", "2015-01-03", { :from => "Dajana" })

emails.each do |email|

puts email.subject

end

The section “Naming variables” in this chapter of Ruby in 100 Minutes (http://tutorials.jumpstartlab.com
/projects/ruby_in_100_minutes.html#2.-variables) also has a couple great examples of good vs bad names.

Also, even though these examples are talking about local variables, the same reasoning applies to
method names, class names, … basically any name that you pick.

Great names reveal your intention while you write this code. They talk about the purpose of your
code, and explain things to your fellow developers.
109 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Oh, and if you’re curious to read more about this, here is an interesting presentation on How to name
things (http://www.slideshare.net/pirhilton/how-to-name-things-the-hardest-problem-in-programming) as well
as a blog post on what programmers �nd the hardest tasks (http://www.itworld.com/article/2833265
/cloud-computing/don-t-go-into-programming-if-you-don-t-have-a-good-thesaurus.html) they face (guess what,
it’s naming things …).

Arguments and parentheses


If you have read carefully, you may have noticed that we said about the code puts 5 that puts is a
method call. And then later we’ve enclosed the value 3 in parentheses when calling the method:
add_two(3) .

That’s right:

 In Ruby, when you de�ne or call (execute, use) a method, you can omit the parentheses.

So these lines mean exactly the same:

puts "Hello!"

puts("Hello!")

And so do these:

add_two 2

add_two(2)

And all of these:

puts add_two 2

puts add_two(2)

puts(add_two 2)

puts(add_two(2))

So when do you use parentheses, and when do you omit them?

There is no clear rule about this, but there are some conventions. For now, you can just stick with the
convention we are using at our study groups, which is:

110 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Use parentheses for all method calls that take arguments, except for the methods puts and p
(and later: require and include ).
If a method does not take any arguments, then do not add empty parentheses, omit them.

So the idiomatic way to write the line above is:

puts add_two(2)

Methods without arguments


Also, so far we’ve only mentioned that sometimes methods do not take any arguments. But we
haven’t looked at an example so far.

Here’s one:

def greet

puts "Oh, hello!"

end

greet

The �rst three lines de�ne a method, and we’ve picked the name greet for it. Again, the method body
contains just a single line.

The last line consists of nothing but the word greet . When Ruby runs this code, and it �nds the word
greet it will know that this refers to the method de�ned earlier, and call it.

So Ruby jumps into the method body (this time it does not bring any objects with it as arguments,
because our method does not need any). It then executes the line puts "Oh, hello!" which prints a
greeting to the screen.

As you can see we do not use any parentheses here. We could do that. The following code would be
perfectly valid, and do exactly the same:

def greet()

puts "Oh, hello!"

end

greet()

However since we can omit the parentheses in this case we do just that. They just add visual noise
and make the code slightly less readable.

111 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Returning nil
Also, you might wonder what’s going on with the return value our our greet method. We just said
that every method call always returns “something” (an object).

That’s right. The method call greet will return the object returned from the last evaluated statement
(which, in our case, is puts "Oh, hello!" ).

What do you think that is?

The method puts always returns nil (because it was written that way): Its purpose is to print
something to the screen, not return something interesting. It’s a command, not a question. So the
most sensible choice for a return value is nil .

So where does the nil object go?

If you look at our example code you notice that we don’t do anything with the return value of the
method call greet : We don’t assign it to a variable. And we don’t pass it to another method call. In
fact, we simply discard it since we’re not interested it in.

In our example that’s just �ne. In practice you should always be aware why you are calling a certain
method. Is it a command like Please print this? Then you probably aren’t interested in the return value
and you can discard it as we’ve done above. Or is it a more like a question What’s the result when you
add 2 to this number? In that case obviously you want to use the return value later.

For the sake of demonstrating that puts and greet indeed return nil we can use p to inspect the
return value like so:

$ irb

> def greet

> puts "Oh, hello!"

> end

> p greet

Oh, hello!

=> nil

Here we go. The => thing in IRB signals that this is the return value. As you can see it �rst prints the
greeting (using puts ) and then, after returning from the method, outputs the nil value.

Terminology: Arguments vs
Parameters
We should mention that we are slightly simplifying terminology here. We con�ate two terms that
112 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

normally would be de�ned separately: We simply use the term “argument” for both the variable
names that are de�ned in the arguments list of the method de�nition, and the value that is passed as
part of the method call.

In programming, normally the “argument list” is called a “parameter list” instead, and a single name
on it is called a “parameter”. On the other hand, only the objects passed when calling the method are
referred to as “arguments”.

E.g. in the code …

def add_two(number)

number + 2

end

puts add_two(3)

… the word number in the �rst line is a “parameter”, whereas 3 in the last line is an “argument”.

We found making this distinction in our beginners classes unnecessarily confusing, and thus ignore it.
We simply call both these things “arguments”, and point out that they create a local variable inside of
the method body.

So, now you know :)

Writing a new method


As programmers we like to split up our tasks, and do one thing after another. This allows us to focus
on one small task, and once we’ve solved it, we move on to the next one.

When you need to add some new functionality to your program you’ll often �nd yourself thinking “I
should add a method for this”: methods add behaviour.

Now, the �rst thing you should ask yourself is: “What is it that this method should do?” The answer to
this gives you a hint for a good method name.

Let’s say you are working on an application that deals with emails, and the thing you are trying to
accomplish is formatting an email. So your method name can be format_email .

With this �rst task solved, knowing the method name, you can already go ahead and write down the
method de�nition:

def format_email

end

113 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

While this is a pretty useless method, since it does nothing at all, it already is a valid method. So that’s
good progress already: you’ve made the �rst step.

The next question to ask is: “Does this method need to be given any information in order to do its
thing?” The answer to this question speci�es the method’s arguments list.

In our example, the answer probably is that, in order to format an email, it needs the email.

So you can now add the argument list to the method:

def format_email(email)

end

With these two things solved you can now start thinking about implementing the method body. How
can you transform the email into some formatted text?

You’d add a new line between def and end , and make sure it’s indented by two spaces (hit tab ,
unless your editor does it for you), and start focussing on the code that makes up the method body:

def format_email(email)

...

end

You see how we’ve split up the task of writing a new method into three smaller tasks, and worked on
each one of them after another.

Even though this might seem trivial at �rst, we recommend you get into this habit, too.

Btw, good editors help you format things. For example, when you are on a line that starts with def
something , and at the end of the line hit return, Sublime will already indent the next line for you by 2
spaces. If you now type end , then Sublime will notice that you are closing the method, and outdent it
again, so def and end sit on the same level. Smart, isn’t it?

Also, you’ll notice that when you type an opening parenthesis ( , then Sublime will add a closing one
) too, but keep your cursor placed between them, so you can type the argument list where it
belongs.

Exercises: Now would be a good time to do some of the exercises on methods.

Advanced Topics

Using Libraries (1)


114 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Our Person class does not de�ne an attribute accessor method for its password, and thus, others
cannot ask for and retrieve it.

However, our person object could freely give them an encrypted version of it.

Actually, this is pretty similar to how authentication often works in real web applications:

Applications do not store your actual password in plain text (hopefully!) That way if, for some reason,
they get hacked, attackers wouldn’t have your actual password. Instead they store an encrypted
version of the password.

Anyhow, we now want to add a method encrypted_password to the Person class, which should return
an encrypted version of the password that is stored in the instance variable @password .

Encryption is one of the things in programming that require very deep expert knowledge, and it is one
of the things we de�nitely wouldn’t want to implement ourselves.

So far, all the Ruby features and methods that we have used are available right away when the Ruby
runtime ruby executes your code. However, Ruby also comes with a ton of functionality that is not
available (loaded) right away. Instead it is stored in so called libraries (which are just Ruby �les, too),
and we have to load them manually, in order to make them available.

To do this, we use the method require , and pass it the name of the library:

require 'digest'

Normally require statements should be placed at the very top of the �le, so it is easy to see what
libraries a particular piece of code (class) uses.

We are going to omit the initialize and name methods here, indicate the omission with the
comment # ... , and just keep the password= attribute writer. In order to run this code make sure
you keep all the methods.

115 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

require 'digest'

class Person

# ...

def password=(password)

@password = password

end

def encrypted_password

Digest::SHA2.hexdigest(@password)

end

end

The library digest that we required includes a something called Digest::SHA2 .

In programming a “digest” is an algorithm to convert one string into another in a way that the original
string cannot be recovered later. However digesting the same string will always result in the same
other, unique string. There are a good bunch of algorithms that do this, and “sha2” is the name of one
of them.

Ok. For our example here we only need to understand that, once we have required the library digest ,
we can use the method Digest::SHA2.hexdigest , and it will encrypt (“digest”) the string that we pass to
it.

If now run the following code:

person = Person.new("Ada")

person.password = "super secret"

puts person.encrypted_password

it will output

eabd522910ccdd77aef079feff0c7bb6486f6ab207ae6d3ed9e671208c92ab0f

which is the digested form of the string "super secret" . Every time you run the program you will see
the same, unique string.

Modules
116 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

It now makes sense to introduce another language feature in Ruby: modules.

In Ruby, modules are somewhat similar to classes: they are things that hold methods, just like classes
do. However, modules can not be instantiated. I.e., it is not possible to create objects from a module.
And modules, unlike classes, therefore do not have a method new .

So, what are modules useful for?

With modules you can share methods between classes: Modules can be included into classes, and this
makes their methods available on the class, just as if we’d copied and pasted these methods over to
the class de�nition.

This is useful if we have methods that we want to reuse in certain classes, but also want to keep them
in a central place, so we do not have to repeat them everywhere.

Let’s have a look at this pretty contrived code:

module Cream

def cream?

true

end

end

class Cookie

include Cream

end

cookie = Cookie.new

p cookie.cream?

We still haven’t been able to come up with a better minimal example of a module and class that
makes more sense than this. And we fully admit that this code is rather weird. However, it’s good
enough to quickly explain how modules work :)

If you run this code it will output true . Why is that?

The method cream? is de�ned on the module Cream , and all it does is always return the value true .
Now, this module is included into the class Cookie . So, if we now instantiate a cookie, we can call the
method cream? on it, and it will return the value true .

Cool. Let’s move on and use this for our Person class, which will hopefully then make more sense.

Let’s assume that our application has other classes that need to encrypt things. And we want to keep
the exact way of how we encrypt things, the implementation in one single place.

Why would we want to do that?

117 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

One reason could be that when we want to switch to a di�erent way of encrypting things (maybe
use a stronger encryption algorithm), we would then only need to change it in this one place, in
our module, and be done with it.
Another reason could be that we want the encryption algorithm to be somehow con�gurable, for
example in a con�guration �le that our application reads. This would then require additional logic
that we would not want to duplicate across all the places where we need to encrypt something:
we’d want all this to be kept in a central place.
Another, much simpler, but sometimes also valid reason could be that we simply want to move
some clutter out of sight, and hide it away in another �le: so we can focus on what our Person
class does, instead of having to look at the nitty-gritty details of how exactly we encrypt things.

Anyhow. Here’s how we can create a meaningful module for our application, and then use it in the
class Person :

require 'digest'

module Encryption

def encrypt(string)

Digest::SHA2.hexdigest(string)

end

end

class Person

include Encryption

# ...

def encrypted_password

encrypt(@password)

end

end

person = Person.new("Ada")

person.password = "super secret"

puts person.encrypted_password

If you run this code, it will print out the same, encrypted version of the password: cool, that’s what we
want.

We have moved the noisy details of the encryption algorithm to a module, and then included the
module to the class Person . This, at the very least, makes the method encrypted_password much
easier to read. Doesn’t it?

118 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

We refer to the process of moving some logic (code) from one method to another new method as
“extracting a method”. In our case we have extracted the method encrypt from the method
encrypt_password . When we do this, methods usually become shorter and more readable.

Private methods
Remember how we said that instance variables store data that is “private” to the object? Instance
variables are only made accessible to the outside world (we say “it is exposed”) if we add attribute
accessors to the class.

In the same way classes sometimes want to keep certain methods private: methods that aren’t
supposed to be called from outside of the object. Only the object itself is supposed to use them
internally, from other methods.

Imagine I am an instance of a class ItalianRestaurant , and I have a method pizza , which is supposed
to return an instance of the class Pizza .

When you approach me, and call the method pizza (i.e. ask me to bring a pizza) then I’ll know what to
do, and how to do it. I’ll get some prepared pizza dough from somewhere, some tomato sauce,
vegetables and other stu� from somewhere else, prepare the pizza, bake it, put it on a nice plate, and
�nally give (return) it to you.

However, you don’t really care about any of these details. You are hungry, and just want the pizza. All
the exact steps involved are something that I keep private to me, and maybe they’ve been our family’s
best kept secret for generations.

This is pretty much how objects work, too. The Italian restaurant object exposes some stu� to the
outer world (you), and keeps other things private. They’ll let you order a pizza, and other things. But
they won’t tell you the exact ingredients of their tomato sauce, or how they manage to make this
damn great pizza dough.

In our Person example it makes sense to make the method encrypt private.

Currently, if you run the following code it will execute just �ne, even though it makes little sense:

person = Person.new("Ada")

p person.encrypt("some other secret")

Why would a person encrypt some arbitrary string for someone else, and return it? This is something
that the person object should keep private. The restaurant wouldn’t turn �our, water, olive oil and
other ingredients into pizza dough for everyone else either.

We can make the method encrypt private like so:

119 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

module Encryption

private

def encrypt(string)

Digest::SHA2.hexdigest(string)

end

end

The keyword private tells Ruby that all methods de�ned from now on, are supposed to be private.
They can be called from within the object (from other methods that the class de�nes), but not from
outside.

If you now try to call the method it will raise an error:

person = Person.new("Ada")

p person.encrypt("super secret")

This will print the error message:

private method `encrypt' called for #<Person:0x007fa179863770 @name="Ada">

Nice. Does this make sense?

Procs
TBD

Yield
TBD

Regular Expressions
Some people, when confronted with a problem, think “I know, I’ll use regular expressions.”
Now they have two problems.

That’s a pretty famous joke, and it refers to the fact that regular expressions (http://en.wikipedia.org
120 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

/wiki/Regular_expression) can be quite a pain to �gure out.

However, once you know some basics about them, they’re also extremely powerful, and you can do
amazing things with them, not only in Ruby, but also, for example, in your editor, and command line
tools.

Regular expressions are sort of a swiss army knife for �nding things in strings (text), extracting parts
of them, or mass replacing certain bits with something else.

E.g. you could do:

Extract area codes from phone numbers.


Validate the format of an email address.
For a list of �les a-01.mpeg , b-02.mpeg , c-03.mpeg , change their names to 01-a.mpeg , 02-b.mpeg ,
03-c.mpeg .

Regular expressions are a language to describe patterns of text. Wikipedia says: a sequence of
characters that de�ne a search pattern.

For example the pattern [0-9]+! means: There needs to be at least one digit, and it needs to be
followed by an exclamation mark. The pattern ([\w]+)-([\d]+)\.mpeg

Does this stu� look scary and cryptic? You bet. That’s why regular expressions have kind of a strange
reputation in programming. They’re super powerful, but they’re also kind of a pain: Like black magic,
this power comes at a price.

The main reason why the language that is de�ned as regular expressions is so hard to read is that it
dates back as far as 1956 (http://en.wikipedia.org/wiki/Regular_expression#History), and their �rst
implementations in programming came up in the late 1960s. Back then every single character of your
code was kinda worth its weight in gold. Memory was extremely limited, and code had to be as terse
as possible.

Now, the most commonly used features of this language are the following:

String literals: �nd a particular piece of text


Anchors: the beginning and the end of the string, or a word
Character classes: de�ne a set of allowed characters
Quanti�ers: de�ne how often a character is expected to occur
Captures: once found, capture a particular part of the text, so we can use it

String literals
Let’s walk through some examples, to make this more practical. Let’s say we have the following text:

text = "A regular expression is a sequence of characters that define a search pattern."

… and we are interested to know if it contains the words character and sentence . In Ruby, we could
use a regular expression like so:

121 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

matches = text.match(/character/)

p matches

This will return an instance of the class MatchData . Whereas, when we look for sentence we’ll get nil :

matches = text.match(/sentence/)

p matches

Note how in Ruby one can de�ne a regular expression by enclosing it with slashes / . There are other
ways to de�ne regular expressions, too, but this is the most common one.

But that’s kinda boring, right? We could just use the method include? for strings, which lets us �gure
out the same thing. Let’s spice this up a little.

Anchors (boundaries)
The most commonly used anchors are: Beginning or end of the string, beginning or end of a line,
beginning or end of a word.

For example:

text = "A regular expression is a sequence of characters that define a search pattern."

puts 'Found "A" at the beginning of the string.' if text.match(/^A/)

puts 'Found "O" at the beginning of the string.' if text.match(/^O/)

puts 'Found the string "character".' if text.match(/character/)

puts 'Found the word "character".' if text.match(/character\b/)

This will output:

Found "A" at the beginning of the string.

Found the string "character".

So it �nds the string “character”, but not the word “character”. This is because the regular expression
/character\b/ requires a word boundary to be found after the string literal (i.e. the literal piece of
text) “character”. Since in our example the text “character” is followed by another “s”, the regular
expression won’t match.

Character classes
122 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Let’s say we want to �nd all the words that start with a vowel. For that we can use a character class,
i.e. a set of allowed characters. Again, we use the anchor word boundary \b , this time to express that
the vowel needs to be at the beginning of the word.

While the method match returns an object (i.e. something “truthy”) when the pattern matches (and
nil when it doesn’t), the method scan returns an array with all the occurances of text that match the
pattern.

So let’s use it:

text = "A regular expression is a sequence of characters that define a search pattern."

p text.scan(/\b[aeiou][a-z]*\b/)

This will output:

["expression", "is", "a", "of", "a"]

Our regular expression de�nes that we’re looking for a piece of text that

starts with a word boundary,


followed by a character that is either “a”, “e”, “i”, “o”, or “u”,
and potentially ( * ) followed by any character between “a” and “z”, and
�nally ends with a word boundary.

We’ll explain the star * quanti�er in a bit.

Notice something though?

Regular expressions are case sensitive. I.e. our piece of code did not match the word “A” in the
beginning of the string. In order to �x that we need to allow uppercase letters as well:

p text.scan(/\b[AEIOUaeiou][a-z]*\b/)

Our output will include the capital “A” at the beginning of the string as well:

["A", "expression", "is", "a", "of", "a"]

This example also demostrates the di�erence between a word boundary and whitespace. A single
space would count as whitespace, and we could use it to match our words, too. However, that would
not work at the beginning and end of a string. And it would not work when our word is followed by
punctuation, such as a comma or fullstop. The word boundary \b allows all of these, too.
123 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

So, what about the star * in the expression above?

Quanti�ers
This is a quanti�er. It means “allow the stu� de�ned before zero, or any number of times”.

In our case it means that we’re looking for a single vowel, followed by either nothing, or one or many
characters between “a” and “z”. This means we match both the words “A” and “a” (not followed by
anything before the word boundary), as well as the words “is”, “of”, and “expression” (which are
followed by one or many characters).

Does that make sense?

Let’s say we want to omit single character words, but we do want to allow all words longer than one
character. For that we could change the “none, one, or many” quanti�er * to another quanti�er +
meaning “at least one, or many”:

p text.scan(/\b[AEIOUaeiou][a-z]+\b/)

This won’t match the words “A” and “a”, and instead output the following:

["expression", "is", "of"]

What if we are looking for words that start with a vowel, and are no more than 2 characters long? We
could use the quanti�er ? which means “none, or exactly one”:

p text.scan(/\b[AEIOUaeiou][a-z]?\b/)

This will output:

["A", "is", "a", "of", "a"]

If we remove the quanti�er entirely, then the regular expression will look for a word that starts with a
vowel, followed by exactly one character:

p text.scan(/\b[AEIOUaeiou][a-z]\b/)

["is", "of"]

124 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Captures
Using the method scan with regular expressions like this is quite useful in many situations. But
sometimes, we need something more powerful.

Imagine we need to �nd all words that are followed by a word that starts with a vowel.

Let’s try using scan for that:

p text.scan(/\b[A-Za-z]+\b +\b[AEIOUaeiou][a-z]*\b/)

The second part of this regular expression is just the same as above: Any word that starts with a
vowel, and that is one or many characters long.

Can you �gure out the �rst part?

It also says: Match something that starts at a word boundary, then has one or many characters
between “A” and “Z” or “a” and “z” (that bit is new: you can combine ranges as character classes), and
that is followed by at least one space.

If you run this you’ll get the following output:

["regular expression", "is a", "sequence of", "define a"]

Looks alright, doesn’t it?

However, we were only interested in words that are immediately followed by a word starting with a
vowel. Our strings contain two words.

So either we’d have to work on these strings more (e.g. use split to split o� the second word). Or
there’s a smarter way of doing the same.

Enter captures.

In regular expressions one can “mark” certain parts of a patterns, saying: “Give me the bits that match
this stu� here”. In order to mark a part of the pattern to be captured you’d enclose it with parenthese,
like so:

/\b([A-Za-z]+)\b +\b[AEIOUaeiou][a-z]*\b/

Note how we’ve enclosed the �rst part of the pattern with parentheses. This means “match the full
pattern, but only capture the parts that we’ve marked as interesting”.

p text.scan(/\b([A-Za-z]+)\b +\b[AEIOUaeiou][a-z]*\b/)

125 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This returns a nested array like this:

[["regular"], ["is"], ["sequence"], ["define"]]

Awesome! We get all the words that we were interested in.

But why is this a nested array? The method scan looks for each bit of text that matches the given
pattern (regular expression). It then extracts all the “marked” (captured) parts from it, and keeps these
as an array. As there can be many occurances that match the pattern, and each of them can have
many captures, we get back a nested array.

Let’s capture the second word (starting with a vowel) as well to demonstrate this:

p text.scan(/\b([A-Za-z]+)\b +\b([AEIOUaeiou][a-z]*)\b/)

This will return:

[["regular", "expression"], ["is", "a"], ["sequence", "of"], ["define", "a"]]

More on character classes


So far we have used character classes like [aeiou] (listing all allowed characters literally), and [a-z]
(specifying a range of characters).

There’s more to these.

One can negate classes by prepending a “not” character ^ inside the square brackets. E.g.
[^AEIOUaeiou] allows every character that is not a vowel. So we can �nd all words that do not start
with a vowel like so:

p text.scan(/\b[^AEIOUaeiou ][^ ]*\b/)

This means: Start at a word boundary, and allow everything that is not a vowel or a space as a �rst
character, when it is optionally followed by one or many characters that are not a space, followed by a
word boundary.

This will output:

["regular", "sequence", "characters", "that", "define", "search", "pattern"]

Also, regular expressions come with “baked-in”, prede�ned classes. For example \d means “any
126 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

digit”. Here’s a list of common classes:

\d is the same as [0-9] (any digit)


\D is the same as [^0-9] (everything except digits)
\w is the same as [A-Za-z_\-] , called word character (i.e. this allows all lowercase and uppercase
latin letters, as well as underscores and dashes)
\W is the same as [^A-Za-z_\-] (everything that is not a word character)
\s means “any whitespace”, including spaces, tabs, and linebreaks
\S everything that is not whitespace

That means we could re�ne our expression from above:

/\b[A-Za-z]+\b +\b[AEIOUaeiou][a-z]*\b/

Like so:

/\b\w+\b +\b[AEIOUaeiou]\w*\b/

This might yield slightly di�erent results if we have words that contained dashes or underscores, but it
is same in our case:

["regular expression", "is a", "sequence of", "define a"]

One can also combine these prede�ned classes with each other, and literal charachters. For example
[\w!?]+ would �nd a sequence of at one or many characters that is a word character, an exclamation
or a question mark.

Anything
Finally, there’s one special character that matches anything: the dot . .

I.e. the regular expression .* matches “any character, zero, or any number of times”. This may be
useful if you are looking, for example, for whatever text is enclosed in parentheses:

text = "Regular expressions are powerful (and sometimes confusing, even to experienced developers)."

p text.scan(/\(.*\)/)

Notice the backslashes before the opening and closing parentheses? We want to match these literal
characters, and not use them with their special meaning of capturing their content here. Therefore we
need to escape them to tell Ruby: Yep, we really mean a parenthesis here.

By the way this will output the following:

127 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

["(and sometimes confusing, even to experienced developers)"]

Whoops. Maybe we actually also do want to capture a part or this, and omit the actual parentheses
from the result. We can do that by placing an extra pair of un-escaped (capturing) parentheses inside
the escaped (literal) ones:

p text.scan(/\((.*)\)/)

And now we’ll get this result, which has the parentheses stripped o�:

[["and sometimes confusing, even to experienced developers"]]

Rubular
Confused? Don’t worry. We all are.

Try to remember some of the most basic, simple stu�. Then try using it, maybe in your text editor,
when you search for a certain phrase. Over time you’ll remember a few more things, bit by bit, and
things will become a little less confusing. Writing a long, complicated regular expression, that actually
works, without thinking, trying, and re-trying a lot is something that only few developers actually can
do - and the author of this book isn’t one of them.

If you cannot �gure out a certain regular expression, or if you want to experiment with something
then Rubular (http://rubular.com) is a great tool for that. Enter some text to the “test string” text area,
and then start writing a regular expression, one bit after another. The app will display the parts that
match, and your captures if you de�ne some.

Exercises (old)
These exercises are an outdated set of exercises that need to be ported and adjusted in order to
re�ect the current order of topics in our book.

Many of them at the moment assume things early on that only are explained later in the book.

Working with Numbers


In order to start irb open your terminal and type irb , then hit the return key ( enter ). In order to
quit irb again (and get back to your system shell prompt) you can type exit or press ctrl-d , which
does the same.

128 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Exercise 1.1
In irb , calculate:

How many hours are in a year.


How many minutes are in a decade?
How many seconds old are you?

Exercise 1.2
What do you think happens when you combine the following �oats and integers?

Try computing these in irb :

3.0 / 2
3 / 2.0
4 ** 2.0
4.1 % 2

Is the result a �oat or an integer?

Exercise 1.3
Methods are a way of “doing something with an object”. E.g. in Ruby, numbers have two methods that
allow you to check whether the number is odd or even.

Look through the documentation for integer (http://ruby-doc.org/core-2.1.5/Fixnum.html) numbers (called


Fixnum ) and �nd the methods that tell if a number is odd or even.

Exercise 1.4
In irb , use these methods to �nd out if certain numbers are odd or even. Numbers like 0, 1, 2, 99,
-502 etc.

 You can use a method by appending a dot . and then the method name to the object. E.g.
-99.abs uses (we also say: “calls”) the method abs on the number -99 .

Try for yourself what it does, and google for “ruby abs” to �nd the documentation (http://ruby-doc.org
/core-2.0/Numeric.html#method-i-abs) for this method.

Working with Strings


In order to start irb open your terminal and type irb , then hit the return key ( enter ). In order to
quit irb again (and get back to your system shell prompt) you can type exit or press ctrl-d , which
does the same.

129 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Exercise 2.1
What do you think this will do?

$ irb

> "hello".length + "world".length

Try it yourself.

Exercise 2.3
Skim through the documentation for strings (http://www.ruby-doc.org/core-2.1.4/String.html) in the Ruby
documentation, and look for a method that prepends one string to another string.

Using that method prepend the string "Learning " to the string "Ruby"

Show solution

Exercise 2.4
Skim through the documentation for strings (http://www.ruby-doc.org/core-2.1.4/String.html) in the Ruby
documentation, and look for a method that removes characters from a string.

Using that method turn the string "Learning Ruby" into the string "Lrnng Rb" .

Show solution

Exercise 2.5
Find out how to convert the string "1.23" into the number 1.23 .

You can either, again, skim the documentation page for strings, or google for “ruby convert string to
number”.

Then also �nd out what method can be used to turn the string "1" into the number 1 (remember
�oats and integers are di�erent kinds of numbers).

Con�rm that you have found the right methods by trying them in irb .

Show solution

Exercise 2.6
There is a method that allows to justify a string, and padding it with another string.

Find that method and use it on the string "Ruby" together with "<3" so that you get the following
string back:

130 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

"Ruby<3<3<3"

We’ll admit that this is a rather creative usage of this method. Normally you’d use it to align strings to
columns (e.g. so that they line up nicely when you format a table). You’ll use this method in other
exercises later on.

Show solution

Working with Arrays (1)


Before you get started, make sure you have your text editor and terminal open, and you have
navigated to your exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 3.1
Create a new, empty �le. Save it as arrays_1-1.rb . Fill in the following line:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# your code goes here

So that, when you run your code (run ruby arrays_1-1.rb ), you get the following output:

Show solution

Exercise 3.2
Copy your �le to a new �le: cp arrays_1-1.rb arrays_1-2.rb , then open this new �le.

Add another line before the line that you just added, so that, when you run your code, you get the
following output:

99

Show solution

Exercise 3.3
Make a new �le arrays_1-3.rb , and �ll in the following line:
131 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# your code goes here

p numbers

So that you get the following output:

[2, 4, 6, 8, 10]

 Read the documentation for the method select that you can use on arrays on the Ruby
documentation (http://www.ruby-doc.org/core-2.2.0/Array.html#method-i-select)

Show solution

Exercise 3.4
Again, copy your last �le to a new �le: cp arrays_1-3.rb arrays_1-4.rb , then open this new �le.

Now change the code that you just added so that you get the following output:

[10, 8, 6, 4, 2]

 The method select that you used in the last exercise returns an array. On this array (the
return value) you can use another method, by, again, just appending a dot . and the
method name to it, i.e., to the end of the line.

 There is another method that reverses the order of the array. You can �nd it by googling for
“ruby array reverse”.

Show solution

Exercise 3.5
Again, copy your last �le to a new �le: cp arrays_1-4.rb arrays_1-5.rb , then open this new �le.

Now change your code so that you get the following output:

[10, 8, 4, 2]

Bonus: Find at least three di�erent solutions for this last change.
132 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Show solution

Working with Hashes (1)


Before you get started, make sure you have your text editor and terminal open, and you have
navigated to your exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 4.1
Make a new �le hashes_1-1.rb , and �ll in the following line:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

So that it prints out dos .

Show solution

Exercise 4.2
Make a new �le hashes_1-2.rb , and �ll in the following line:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

puts dictionary[:four]

So that it prints out cuatro .

Show solution

Exercise 4.3
Copy that �le to a new �le cp hashes_1-2.rb hashes_1-3.rb , and change your code so that it prints out
the following.

Cuatro

 There’s a method that upcases the �rst letter of a string. Find it by googling for “ruby string
upcase �rst letter”.

133 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Show solution

Exercise 4.4
There is a method on hashes that allows to check if a certain key is de�ned on the hash. Find that
method by googling for “ruby hash key de�ned”.

Try this method in irb by creating a hash like the one above, calling the method and passing keys like
:one , :two , :four , and :ten .

Show solution

Exercise 4.5
There is a method on hashes that �ips keys and values. Find that method on the Ruby documentation
about hashes (http://www.ruby-doc.org/core-2.2.0/Hash.html)

Make a new �le hashes_1-5.rb , and �ll in the following line using that method:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

This should then output:

{ 'uno' => :one, 'dos' => :two, 'tres' => :three }

Show solution

De�ning methods
Exercise 5.1
Write a method greet that takes a name, prepends "Hello " , and appends an exclamation mark
"!" :

def greet(name)

# your code goes here

end

puts greet("Ada")

134 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

This should print out Hello Ada! .

Show solution

Exercise 5.2
Once you’ve implemented the method this should print out: Hello Ada! .

Now change your method so that instead of always using "Hello " it picks a random string from the
array ["Hello", "Hi", "Ohai", "ZOMG"] .

Every time you run the program it should print out either "Hello Ada!" , "Hi Ada!" , "Ohai Ada!" , or
"ZOMG Ada!" .

 The method shuffle on arrays does, well, shu�e the array :) That means it changes the
order of the elements in the array in a random way.

Show solution

Exercise 5.3
Write a method that converts a distance (a number) from miles to kilometers:

def miles_to_kilometers(miles)

# your code goes here

end

puts miles_to_kilometers(25)

This should print out:

40.2336

Show solution

Exercise 5.4
Write a method leap_year? that takes a year (a number), and calculates if it is a leap year.

135 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

def leap_year?(year)

# your code goes here

end

p leap_year?(2012)

p leap_year?(2015)

This should print out:

true

false

Hint: The operator % returns the rest of a division. E.g. 14 % 3 returns 2 .

Bonus: Also make it so that the method returns true for the year 2000 and false for 1900 …
because that’s really the de�nition of leap years.

Show solution

Working with Arrays (2)


Note: At the moment these exercises require reading up until “Block return values”. You should know
how to use the method collect on arrays.

Before you get started, make sure you have your text editor and terminal open, and you have
navigated to your exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 6.1
Create a new, empty �le. Save it as arrays_2-1.rb . Fill in the following line:

words = ["one", "two", "three", "four", "five"]

# your code goes here

p words

So that you get the following output:

["one", "three", "five"]

136 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Show solution

Exercise 6.2
Copy your �le to a new �le: cp arrays_2-1.rb arrays_2-2.rb , then open this new �le.

Now change your code so that you get the following output:

["One", "Three", "Five"]

 Google for ruby string uppercase first letter .

Show solution

Exercise 6.3
Copy your �le to a new �le: cp arrays_2-2.rb arrays_2-3.rb , then open this new �le.

Now change your code so that you get the following output:

["One <3", "Three <3", "Five <3"]

 Use string interpolation for this.

Show solution

Exercise 6.4
Copy your �le to a new �le: cp arrays_2-3.rb arrays_2-4.rb , then open this new �le.

Now change your code so that you get the following output:

["One <3", "Three <3<3<3", "Five <3<3<3<3<3"]

Show solution

Exercise 6.5
Copy your �le to a new �le: cp arrays_2-4.rb arrays_2-5.rb , then open this new �le.

Now change your code so that you get the following output (hint: again, that’s now a string, not an
array):

137 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

One <3, Three <3<3<3, Five <3<3<3<3<3

Show solution

Exercise 6.6
Copy your �le to a new �le: cp arrays_2-5.rb arrays_2-6.rb , then open this new �le.

Now change your code so that you get the following output, using the newline character "\n" :

One <3

Three <3<3<3

Five <3<3<3<3<3

Show solution

Exercise 6.7
Copy your �le to a new �le: cp arrays_2-6.rb arrays_2-7.rb , then open this new �le.

Now change your code so that you get the following output, aligning the second column:

One <3

Three <3<3<3

Five <3<3<3<3<3

 As you may guess, strings have a method that is helpful for this. Ask Google: “ruby string
align”.

Show solution

Working with Nested Arrays


Note: At the moment these exercises require reading up until “Block return values”. You should know
how to use the method collect on arrays.

Before you get started, make sure you have your text editor and terminal open, and you have
navigated to your exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 7.1
138 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Make a new �le nested_arrays-1.rb , and �ll in the following line:

numbers = [

[1, 2, 3],

[4, 5, 6],

[7, 8, 9]

# your code goes here

p sums

So that you get the following output:

[6, 15, 24]

Show solution

Exercise 7.2
Make a new �le nested_arrays-2.rb , and �ll in the following line:

Fill in the following line

numbers = [

[1, 2, 3],

[2, 2, 2],

[3, 2, 1]

# your code goes here

lines.each { |line| puts line }

So that you get the following output:

* ** ***

** ** **

*** ** *

Show solution

139 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Working with Hashes (2)


Exercise 8.1
Make a new �le hashes_2-1.rb , and dd the following lines:

languages = {

:de => 'German',

:en => 'English',

:es => 'Spanish',

dictionary = {

:de => { :one => 'eins', :two => 'zwei', :three => 'drei' },

:en => { :one => 'one', :two => 'two', :three => 'three' },

:es => { :one => 'uno', :two => 'dos', :three => 'tres' }

Now, at the end of the �le, add code that prints out the following:

In German, eins means one, zwei means two, drei means three.

In Spanish, uno means one, duo means two, tres means three.

Show solution

Exercise 8.2
Now, in a new �le hashes_2-2.rb , with the same hashes from above, add code that prints out the
following table:

de eins zwei drei

en one two three

es uno dos tres

Show solution

Exercise 8.3
Copy your �le to a new �le cp hashes_2-2.rb hashes_2-3.rb and change your code so that it aligns the
table columns:
140 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

de eins zwei drei

en one two three

es uno dos tres

Show solution

Exercise 8.4
Copy your �le to a new �le cp hashes_2-3.rb hashes_2-4.rb and change your code so that it adds
delimiters:

| de | eins | zwei | drei |

| en | one | two | three |

| es | uno | dos | tres |

Show solution

Truthiness
Exercise 9.1
Make a new �le truthiness-1.rb , and add the following lines:

This exercise is about validating what we’ve learned about truthiness.

You have the following array:

objects = [true, false, 0, 1, "", [], Object.new, Class.new, Module.new]

Add some code that outputs the following table. The last column should be �lled in with by either
true or false depending what the operation !!object , which is the same as not not object` for
each of the objects returns:

141 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

object | !!object

true | [true|false]

false | [true|false]

nil | [true|false]

0 | [true|false]

1 | [true|false]

"" | [true|false]

[] | [true|false]

#<Object:0x007fb3dc0ea1b8> | [true|false]

#<Class:0x007fb3dc0e2cd8> | [true|false]

#<Module:0x007fb3dc0d9ea8> | [true|false]

You can use the method inspect in order to, for each of the values, get a representation that looks
like the code.

Of course you will get di�erent object ids for the object, class, and module instances everytime you
run your code.

So let’s prettify this table by removing the object ids. You can do this calling sub(/:.*>/, ">") on
whatever inspect returns.

Your table should now look like this:

object | !!object

true | true

false | false

nil | false

0 | true

1 | true

"" | true

[] | true

#<Object> | true

#<Class> | true

#<Module> | true

Show solution

Bonus: Exercise 9.2


Copy your �le to a new �le truthiness-2.rb , and change your code so that it outputs the following
table. Fill each cell with the result that == returns for each combination.

142 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

| true | false | 0 | 1 | "" | [] | #<Object> | #<Cla

true | | | | | | | |

false | | | | | | | |

0 | | | | | | | |

1 | | | | | | | |

"" | | | | | | | |

[] | | | | | | | |

#<Object> | | | | | | | |

#<Class> | | | | | | | |

#<Module> | | | | | | | |

Tip: Break this up in sub-tasks:

Write some code that collects an array of arrays containing all rows: An array rows that has many
arrays, each of which holds 9 results (cells).
Add the value’s representation to the beginning to the row. If you don’t know how, google for
“ruby array add to beginning”
Make sure each of the cells is 9 characters wide.
Join each of the row with the string " | " .
Add the table headers row.
Join all rows with the string "\n" (newline), and output the result.

Show solution

The Email Class


Exercise 10.1
In a new �le email_1.rb write a class Email that has a subject , date , and from attribute. Make it so
that these attributes can be populated through new and initialize .

The following code

143 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Email

# fill in this class body

end

email = Email.new("Homework this week", "2014-12-01", "Ferdous")

puts "Date: #{email.date}"

puts "From: #{email.from}"

puts "Subject: #{email.subject}"

should then output the following:

Date: 2014-12-01

From: Ferdous

Subject: Homework this week

Show solution

Exercise 10.2
Once you have this class, copy your �le to email_2.rb .

Change your class so that the initialize method now takes a subject string, and a headers hash.
This is then more in line with how actual emails are stored in the real world: the values date and
from are stored on a hash, which is called the “email headers”.

Doing so, in the code above the only line you should change is the one that instantiates the email
object, which should now read:

email = Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Ferdous" })

Your program should now still produce the same output.

Show solution

The Mailbox Class


Exercise 11.1
In a new �le mailbox-1.rb Write a class that has a name and emails attribute. Make it so that the
144 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

these attributes can be populated through the initialize method ( name being a string, and emails
being an array of Email instances).

The following code

class Email

# your class from the last exercise

end

class Mailbox

# fill in this class body

end

emails = [

Email.new("Homework this week", { :date => "2014-12-01", :from => "Ferdous" }),

Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Dajana" }),

Email.new("Re: Homework this week", { :date => "2014-12-02", :from => "Ariane" })

mailbox = Mailbox.new("Ruby Study Group", emails)

mailbox.emails.each do |email|

puts "Date: #{email.date}"

puts "From: #{email.from}"

puts "Subject: #{email.subject}"

puts

end

should then output the following:

145 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Date: 2014-12-01

From: Ferdous

Subject: Homework this week

Date: 2014-12-01

From: Dajana

Subject: Keep on coding! :)

Date: 2014-12-02

From: Arianne

Subject: Re: Homework this week

Show solution

The Mailbox Text Formatter


The mailbox text formatter exercise is a milestone in the beginners group curriculum, and it may take
a little bit longer to complete it. That is �ne, and, to some extent, the point :)

Exercise 12.1
Make a new �le mailbox_text-1.rb . Fill in and complete the following class de�nitions:

146 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

class Email

# your class from the last exercise

end

class Mailbox

# your class from the last exercise

end

class MailboxTextFormatter

# fill in this class body

end

emails = [

Email.new("Homework this week", { :date => "2014-12-01", :from => "Ferdous" }),

Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Dajana" }),

Email.new("Re: Homework this week", { :date => "2014-12-02", :from => "Ariane" })

mailbox = Mailbox.new("Ruby Study Group", emails)

formatter = MailboxTextFormatter.new(mailbox)

puts formatter.format

Your goal is to complete the code in a way so it outputs the following:

Mailbox: Ruby Study Group

+------------+---------+------------------------+

| Date | From | Subject |

+------------+---------+------------------------+

| 2014-12-01 | Ferdous | Homework this week |

| 2014-12-01 | Dajana | Keep on coding! :) |

| 2014-12-02 | Ariane | Re: Homework this week |

+------------+---------+------------------------+

You are allowed to add as many methods to the classes Email , Mailbox and MailboxTextFormatter as
you deem useful. In your �nal solution you are not allowed to change any of the code outside (after)
the class de�nitions. For debugging purposes, you can, of course, change all the code you want :)

If you do this exercise in one of our study groups then best do it together with someone else. We
found pairs to work best, and a three person team would be better than doing it on your own.
147 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Try to come up with a working solution �rst. It doesn’t matter how elegant, generic, or pretty it is.
Whatever produces the required output is �ne for a �rst solution.

Then, later, look at your code, and try to improve it by cleaning up everything that you don’t like, or
deam ugly.

Eventually, one goal to aim for would be: Adding another column to the table only requires mimimal
changes, e.g. changes to one or two places in your formatter class.

Show solution

The Mailbox Html Formatter


Separation of concerns
One question that may have come up while working on the mailbox text formatter exercise is:

Why would we have a separate class for formatting the ASCII table (that is, a plain text table that uses
characters like + , - , and | )?

The reason is: We want each one of our classes to encapsulate one concept that is useful in our
application. We also say: each one of our classes should be concerned with one responsibility.

An email vaguely resembles the concept of an analog letter, written on paper: some message is being
sent from one person to another. Nowadays everyone knows what an email is: it stores all
information about this particular message. The same is true for mailboxes, which are used to store a
bunch of emails. Formatting a number of emails in order to be displayed on a text based terminal is a
very di�erent concept, and concern.

Therefore it makes a lot of sense to have three di�erent classes implement each one of these
concepts, or concerns. And it even makes so much sense that it is called a design principle in
programming: The principle of separation of concerns (http://www.wikiwand.com
/en/Separation_of_concerns).

Aside from being comprehensible and mapping to concepts that we already know, one other
advantage is: We can now easily implement other formatter classes that format our emails in a
di�erent way, suitable to be displayed in other media.

And that’s what this exercise is about: We want to display our mailbox contents in HTML, the format
that browsers like to use. If you are unfamiliar with what HTML is, and how it looks like, you can read
up on it here (http://webapps-for-beginners.rubymonstas.org/html.html). This will be our �rst step towards
learning how to build a web application.

Model, View, Controller


Before we get to that, we’d like to point out one other aspect, that you’ll remember when we get to
talk about the architecture that Rails use to structure and separate concerns, called “model, view,
controller”.
148 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

The two classes Email and Mailbox in your application are models: they are concerned with
modelling those “real-world” things that your users are interested in: they want to work with
emails.
The class MailboxTextFormatter on the other hand is a view: It is used in order to generate a
certain representation, in a format that is suitable to a certain medium (the terminal, in our case).
You don’t have a controller class so far, but the little bit of code at the end of the �le does what a
controller usually would do: it generates some models (the emails, and the mailbox objects) and
passes them to the view (the formatter) in order to be rendered into something that can then be
returned and displayed.

If this doesn’t make a whole lot of sense to you at the moment, don’t worry. You’ll understand it more
once we build our �rst Rails application.

Exercise 13.1
Ok, now to our exercise. We will start over with the same code again, except that our formatter class
now will be called MailboxHtmlFormatter .

Copy your �le mailbox_text-1.rb to mailbox_html-1.rb and change it like so. Then �ll in the
MailboxHtmlFormatter class.

class Email

# your class from the last exercise

end

class Mailbox

# your class from the last exercise

end

class MailboxHtmlFormatter

# fill in this class body

end

emails = [

Email.new("Homework this week", { :date => "2014-12-01", :from => "Ferdous" }),

Email.new("Keep on coding! :)", { :date => "2014-12-01", :from => "Dajana" }),

Email.new("Re: Homework this week", { :date => "2014-12-02", :from => "Ariane" })

mailbox = Mailbox.new("Ruby Study Group", emails)

formatter = MailboxHtmlFormatter.new(mailbox)

puts formatter.format

149 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Your goal is to complete the code in a way so it outputs the following:

150 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

<html>

<head>

<style>

table {

border-collapse: collapse;

td, th {

border: 1px solid black;

padding: 1em;

</style>

</head>

<body>

<h1>Ruby Study Group</h1>

<table>

<thead>

<tr>

<th>Date</th>

<th>From</th>

<th>Subject</th>

</tr>

</thead>

<tbody>

<tr>

<td>2014-12-01</td>

<td>Ferdous</td>

<td>Homework this week</td>

</tr>

<tr>

<td>2014-12-01</td>

<td>Dajana</td>

<td>Keep on coding! :)</td>

</tr>

<tr>

<td>2014-12-02</td>

<td>Ariane</td>

<td>Re: Homework this week</td>

</tr>

</tbody>

</table>

151 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

</body>

</html>

Does that look scary? A little bit, maybe. It’s probably fair to say that manually writing HTML isn’t very
popular amongst most programmers. Therefore there are quite a few tools that make our lives easier.
And your task is to write such a tool.

Also, this exercise should actually be easier for you to complete than the previous one. You already
have a bunch of practice in iterating over emails, and working with arrays and strings. And this time,
you don’t need to deal with the maximum length of strings per column. You can just interpolate things
together.

Show solution

Storing our HTML to a File


Exercise 14.1
In this exercise our goal is to store the generated HTML for our mailbox to a �le, so that we can �nally
view it in an actual browser.

Your objective is to write a �le (using Ruby) that contains all the HTML from the last exercise.

Building on the last exercise, copy your �le to a new �le cp mailbox_html-1.rb mailbox_file-1.rb and
change the last line:

Instead of passing the HTML to puts you should be passing it to a di�erent method, so that running
your program writes the HTML �le that we are after. In order to �nd that method try googling for
“ruby write �le”. Call this �le emails.html .

When you open this �le in a text editor you should see the same HTML from the last exercise. When
you open it in your browser it should look like this:

152 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Show solution

Reading from a CSV File


So far our program has all the email data hardcoded: All the data is baked right into our code.
Everytime you run it, it will display all the same emails. Obviously that’s not a very useful for a real
world program.

Let’s change this to read our data from an external data source instead.

One very simple and pretty popular way to store data to �les is using the format CSV. This stands for
“comma separated values” (although, often times semicolons are used as a separator instead of
commas), and it is something that spreadsheets can read and export. Being able to work with CSV can
be pretty handy: just write a little Ruby script, and �lter that data, or work with it otherwise.

The �rst line in the code below require "csv" makes Ruby’s CSV library available to your program so
that you can then use the class CSV .

Exercise 15.1
Building on the same code from the last exercises, your objective is to read the email data from a �le
emails.csv . This �le should be stored in the same directory as your Ruby program, and contain the
following data:

Date,From,Subject

2014-12-01,Ferdous,Homework this week

2014-12-01,Dajana,Keep on coding! :)

2014-12-02,Ariane,Re: Homework this week

2014-12-11,Maria,I'm back in Berlin

153 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

You can create that �le by copying the four lines from above to your editor.

In order to complete this exercise you’ll need to �nd out how to:

Read the contents of a �le to Ruby, as a string


Parse this string as CSV (google for “ruby csv” and/or look at the documentation)
For each of the rows, ignoring the header line, create an Email instance

In other words, you should replace the following lines of code:

emails = [

Email.new("Homework this week", { :from => "Ferdous", :date => "2014-12-01" }),

Email.new("Keep on coding! :)", { :from => "Dajana", :date => "2014-12-01" }),

Email.new("Re: Homework this week", { :from => "Ariane", :date => "2014-12-02" })

Once you have �gured out how to read and parse the CSV �le, and create an array of Email instances
out of that data, your next task is to encapsulate all of that into a class EmailsCsvStore . This class
should take a �lename, and have a method read , which returns the emails array.

In the end that part of the code should read:

154 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

require "csv"

class Email

# your class from the last exercise

end

class Mailbox

# your class from the last exercise

end

class MailboxHtmlFormatter

# your class from the last exercise

end

class EmailsCsvStore

def initialize(filename)

# fill in this method

end

def read

# fill in this method

end

end

store = EmailsCsvStore.new('emails.csv')

emails = store.read

mailbox = Mailbox.new("Ruby Study Group", emails)

formatter = MailboxHtmlFormatter.new(mailbox)

# your code from the last exercise, writing the file

Show solution

Exercises
If you haven’t done the try ruby (http://tryruby.org) course already, we recommend you do at least a
couple of lessons over there too.

Whenever you sit down to do some of the exercises in this book make sure you have your text editor
155 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

and terminal open. In your terminal:

Create a new directory where you want to keep Ruby �les for our exercises. For example: ~/ruby-
for-beginners/exercises . In order to create that directory in the terminal you can run: mkdir
~/ruby-for-beginners/exercises .

Then navigate to this directory: cd ~/ruby-for-beginners/exercises

In order to check if you are in the right directory you can always run: pwd . (That’s short for print
working directory, meaning, it prints the name of the current directory.)

In order to see all the �les and subdirectories contained in the current directory you can run ls .

Credits: The exercises 1.1, 1.2, and 2.1 are taken from Introduction to Ruby (http://www.ruby-doc.org/docs/Tutorial/part_01
/�rst_steps.html).

Working with Numbers


In order to do these exercises you should have read at least the chapter about
[built_in_classes/numbers.html].

Exercise 1.1
In irb , calcluate:

How many hours are in a year.


How many minutes are in a decade?
How many seconds old are you?

 To start irb open your terminal and type irb , then hit the return key ( enter ). To quit it
(and get back to your system shell prompt) type exit or press ctrl-d .

Exercise 1.2
What do you think happens when you combine �oats and integers the following in the following
calculations?

Try computing these in irb :

3 / 2
3.0 / 2
3 / 2.0
4 * 2.0
0 + 1

Is the result a �oat or an integer?


156 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Exercise 1.3
Try �nding out what “modulo” means by asking Google.

In Ruby (and many other languages) the operator for modulo is % .

Try the following in irb :

5 % 2
15 % 2
505 % 2

And:

8 % 5
9 % 5
10 % 5
11 % 5

Exercise 1.4
Methods are a way of “doing something with an object”, and you’ll learn a lot more about them in a
few chapters.

In Ruby, numbers have methods that allow you to check whether the number is odd or even.

Look through the documentation for integer (http://ruby-doc.org/core-2.2.2/Integer.html) numbers and


�nd the methods that tell if a number is odd or even.

Look at the examples for some of the other methods on that page.

 You can use a method by appending a dot . and then the method name to the object. E.g.
-99.abs uses (we also say: “calls”) the method abs on the number -99 .

Exercise 1.5
In irb , use these methods to �nd out if certain numbers are odd or even.

Try a bunch of numbers like 0, 1, 2, 99, -502 etc.

Try for yourself what it does, and google for “ruby number odd even” to �nd the documentation
(http://ruby-doc.org/core-2.2.2/Integer.html#method-i-odd-3F) for these methods.

Show solution

Working with Strings


In order to do these exercises you should have read at least the chapter about
157 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

[built_in_classes/strings.html].

Exercise 2.1
In irb try �guring out how to produce the following String: "Ruby<3<3<3" .

Try using no more than two other String objects.

Show solution

 To start irb open your terminal and type irb , then hit the return key ( enter ). To quit it
(and get back to your system shell prompt) type exit or press ctrl-d .

Exercise 2.2
Look through the documentation for Strings (http://ruby-doc.org/core-2.1.5/String.html).

Do you spot any interesting methods?

Exercise 2.3
What do you think this will do?

$ irb

> "hello".length + "world".length

Try it yourself in irb .

Show solution

Exercise 2.4
Look through the documentation for Strings (http://ruby-doc.org/core-2.1.5/String.html), and �nd out how
to convert the string "1.23" into the number 1.23 .

If you can’t �nd it, google for “ruby convert string to �oat”.

Then also �nd out what method can be used to turn the string "1" into the number 1 (remember
�oats and integers are di�erent kinds of numbers).

Con�rm that you have found the right methods by trying them in irb .

Show solution

Working with Arrays (1)


158 of 162 19/11/2019 15:51
Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

In order to do these exercises you should have read at least the chapter about
[built_in_classes/arrays.html].

 Make sure you have your text editor and terminal open, and you have navigated to your
exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 3.1
In the Array [1, 2, 3, 4, 5] , what’s the index of the number 4 ?

Show solution

Exercise 3.2
In irb , how can you ask the Array, and check if your previous answer was correct?

Show solution

Exercise 3.3
In irb , how can you ask the Array for the number of elements it contains?

Show solution

Exercise 3.1
Create a new, empty �le. Save it as arrays_1-1.rb . Fill in the following line:

numbers = [1, 2, 3, 4, 5, 6]

# your code goes here

… so that, when you run your code (run ruby arrays_1-1.rb ), you get the following output:

Show solution

Exercise 3.2
Copy your �le to a new �le: cp arrays_1-1.rb arrays_1-2.rb , then open this new �le.

Add another line before the line that you just added, so that, when you run your code, you get the
following output:

159 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

99

Show solution

Exercise 3.3
Make a new �le arrays_1-3.rb , and �ll in the following line:

numbers = [1, 2, 3, 4, 5, 6]

# your code goes here

p numbers

… so that you get the following output:

[2, 4, 6]

 You know how to get the individual numbers. And you know that you can list things
separated by comma, and enclosed with square brackets in order to get a new Array. Try
combining this, and “listing” the code that gets a number from the array.

Show solution

Exercise 3.4
Again, copy your last �le to a new �le: cp arrays_1-3.rb arrays_1-4.rb , then open this new �le.

Now add another line after the one that you just added (i.e. before you �nally output the array using
p ).

Try to �gure out how to transform your Array so you get the following output:

[6, 4, 2]

 Before you do anything else, try describing the problem in English. What verb do you use to
describe this transformation?

 Look through the methods listed on the left side of the documentation for Arrays
(http://ruby-doc.org/core-2.1.5/Array.html). to see if any of these describes what you’re looking

160 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

for.

Show solution

Working with Hashes (1)


In order to do these exercises you should have read at least the chapter about
[built_in_classes/hashes.html].

 Make sure you have your text editor and terminal open, and you have navigated to your
exercises directory in the terminal. E.g. cd ~/ruby-for-beginners/exercises .

Exercise 4.1
Make a new �le hashes_1-1.rb , and �ll in the following line:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

… so that it prints out dos .

Show solution

Exercise 4.2
Make a new �le hashes_1-2.rb , and �ll in the following line:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

puts dictionary[:four]

… so that it prints out cuatro .

Show solution

Exercise 4.3
Copy that �le to a new �le cp hashes_1-2.rb hashes_1-3.rb , and change your code so that it prints out
the following.

161 of 162 19/11/2019 15:51


Ruby For Beginners | Ruby for Beginners http://ruby-for-beginners.rubymonstas.org/print...

Cuatro

 There’s a method that upcases the �rst letter of a string. Find it by googling for “ruby string
upcase �rst letter”.

Show solution

Exercise 4.4
There is a method on hashes that allows to check if a certain key is de�ned on the hash. Find that
method by googling for “ruby hash key de�ned”.

Try this method in irb by creating a hash like the one above, calling the method and passing keys like
:one , :two , :four , and :ten .

Show solution

Exercise 4.5
There is a method on hashes that �ips keys and values. Find that method on the Ruby documentation
about Hashes (http://www.ruby-doc.org/core-2.2.0/Hash.html)

Make a new �le hashes_1-5.rb , and �ll in the following line using that method:

dictionary = { :one => 'uno', :two => 'dos', :three => 'tres' }

# your code goes here

This should then output:

{ 'uno' => :one, 'dos' => :two, 'tres' => :three }

Show solution

Ruby Monstas (http://rubymonstas.org) Ruby For Beginners (http://ruby-for-beginners.rubymonstas.org)


Webapps For Beginners (http://webapps-for-beginners.rubymonstas.org)
Testing For Beginners (http://testing-for-beginners.rubymonstas.org) Email
Twitter (https://twitter.com/rubymonstas) GitHub (https://github.com/rubymonsters)
License (https://creativecommons.org/licenses/by-sa/2.0/) Imprint (http://foundation.travis-ci.org/imprint/)

162 of 162 19/11/2019 15:51

S-ar putea să vă placă și