Learning Ruby: Playing with irb
Tags: ruby, learning
Published: 2018-08-21 14:47:58

---
title: Learning Ruby: Playing with irb
published: true
description: A journey of a thousand miles always begin with a REPL
tags: ruby, learning
cover_image: https://thepracticaldev.s3.amazonaws.com/i/7iej0f1oun8dyu7ffqdc.png
---

## Introduction

I have this book, called *Beginning Ruby*, written by Peter Cooper. It's one of the first book I've bought about programming. I've read... 20 pages probably... For some reason, I barely started it. The book is getting *old*, in programming terms, but I feel like learning a little bit of Ruby, and I feel like it will get the job done to teach me the basics. I never used Ruby before, so I'm starting from scratch here.

## irb ( Interactive RuBy )

*Note:* I'll assume you have Ruby installed on your machine. You can check by running `ruby -v` in a terminal. You should get something like: 

```
➜  ~ git:(master) ✗ ruby -v
ruby 2.3.3p222 (2016-11-21 revision 56859) [universal.x86_64-darwin17]
```

To start the ruby's REPL, called irb, simply type *irb* and press Enter:

```
➜  ~ git:(master) ✗ irb
irb(main):001:0>
```

To exit the REPL, type *exit* and press Enter.

For this article, I think I will only use irb.

### As basic as it gets

From what I read, Ruby aims to be a very readable language, close to the English language. To follow the ancient traditions of our people, we must print a friendly greeting to our terminal. Let's type the following in our terminal:

`10.times do print "Hello Ruby" end`

Well, it is true it reads like English. You could read that to anyone understanding English and they would understand what you are talking about. We can guess pretty easily what this command will do:

```
Hello RubyHello RubyHello RubyHello RubyHello RubyHello RubyHello RubyHello RubyHello RubyHello Ruby=> 10
```

Prints 10 times "Hello Ruby" !!! For now, I think it's safe to forget the *=> 10* at the end. I don't know what it means yet :D

### Maths

Of course, we can also do some maths:

```
irb(main):005:0> 2+2
=> 4
irb(main):006:0> 3-2
=> 1
irb(main):007:0> 8-45
=> -37
irb(main):009:0> 4*5
=> 20
irb(main):008:0> 10/3
=> 3
```

Notice the result of the last operation. Returns 3. We know it's not true. If you provide Ruby with integers, you will get an integer as a result. You want a floating point number? Provide floating points numbers in the operation:

```
irb(main):013:0> 10.0 / 3
=> 3.3333333333333335
irb(main):014:0> 10 / 3.0
=> 3.3333333333333335
```

Tadaaaa!!

Another issue you might encounter, if you are trying the following:

```
irb(main):019:0> print 42 + " is the answer to the universe"
TypeError: String can't be coerced into Fixnum
	from (irb):19:in `+'
	from (irb):19
	from /usr/bin/irb:11:in `<main>'
```

OR:

```
irb(main):020:0> print "The answer to the universe is " + 6*7
TypeError: no implicit conversion of Fixnum into String
	from (irb):20:in `+'
	from (irb):20
	from /usr/bin/irb:11:in `<main>'
```

Strings and Numbers can't be associated this way. To solve this, you can do:

```
irb(main):021:0> print "The answer to the universe is ",  6*7
The answer to the universe is 42=> nil

irb(main):022:0> print 42, " is the answer to the universe"
42 is the answer to the universe=> nil
```

We added a comma instead of a *+*, and it works as expected!

## Objects!! Objects everywheeeere!!

Ruby is an object-oriented programming language. Any concept you can think of can be represented as an object in Ruby. If you've used another object-oriented language, this may look familiar. Let's see how Ruby does it.

Let's create a concept called Book:

```
irb(main):023:0> class Book
irb(main):024:1> attr_accessor :title, :author, :year
irb(main):025:1> end
=> nil
```

So, in Ruby, we call a concept a *class*. So we create a Book class. Always starts with a capital letter. Then, we define three attributes to our Book class: title, author and year. Finally, the *end* keyword tells Ruby we are done defining our concept.

*Book* is the concept, an object is a thing based on that concept. The book 1984 written by George Orwell could be an object based on the Book concept for example.

### Using our concept

Let's create a variable to store an *instance* of our Book concept.

```
irb(main):028:0> book_instance = Book.new
=> #<Book:0x007fdc17898208>
``` 

We created a new Book instance by called the *new* method on the Book class. We stored that instance inside a variable called *book_instance*. Now, as long as your REPL lives, *book_instance* is an instance of the Book class. Let's change a few things about our book instance:

```
irb(main):029:0> book_instance.title = "1984"
=> "1984"
irb(main):034:0> book_instance.author = "George Orwell"
=> "George Orwell"
irb(main):035:0> book_instance.year = 1948
=> 1948
```

Here, we gave the book_instance attributes a value. As you can see, there are no restrictions on the type of data you give to those attributes. I could have written  1984 instead of "1984" and no errors would have appeared.

### Retrieving data

To print the attributes:

```
irb(main):036:0> puts book_instance.year
1948
=> nil
irb(main):037:0> puts book_instance.title
1984
=> nil
```

*puts* is like *print*. The difference is that *puts* adds a newline character at the end ( and starts a new line ).

## Inheritance

Having a Book concept is fine, but there are a lot of different books available. We can make concepts inherit from other concepts. 

```
irb(main):038:0> class Novel < Book
irb(main):039:1> attr_accessor :genre
irb(main):040:1> end
=> nil
```

The *Novel* concept inherits from the *Book* concept. This means that the Novel will have access to the Book attributes. Let's create a Novel instance:

```
irb(main):041:0> novel_instance = Novel.new
=> #<Novel:0x007fdc17818aa8>
irb(main):043:0> novel_instance.title = "Notre Dame de Paris"
=> "Notre Dame de Paris"
irb(main):044:0> novel_instance.genre = "Romance"
=> "Romance"
```

Our *novel_instance* has access to the Book attributes ( such as title ), and has its own attributes ( here genre ). **BUT**, the Book concept doesn't have access to the Novel attributes:

```
irb(main):045:0> newbook = Book.new
=> #<Book:0x007fdc17013650>
irb(main):046:0> Book.genre = "Romance"
NoMethodError: undefined method `genre=' for Book:Class
	from (irb):46
	from /usr/bin/irb:11:in `<main>'
```

And, if we create another concept, inheriting from Book, that concept will only have access to its attributes, and the Book attributes, *not* the Novel attributes.

```
irb(main):007:0> class Magazine < Book
irb(main):008:1> attr_accessor :type
irb(main):009:1> end
=> nil

irb(main):017:0> mag_instance = Magazine.new
=> #<Magazine:0x007fcabc05db90>
irb(main):018:0> mag_instance.type = "Periodical"
=> "Periodical"
irb(main):019:0> mag_instance.title = "GQ"
=> "GQ"
irb(main):020:0> mag_instance.genre = "ERROOOOR"
NoMethodError: undefined method `genre=' for #<Magazine:0x007fcabc05db90 @type="Periodical", @title="GQ">
	from (irb):20
	from /usr/bin/irb:11:in `<main>'
```

We created a *Magazine* concept which inherits from Book. Magazine doesn't have access to the Novel attributes, only to its attributes and the one of its parent.

### Methods

Classes can have methods, instructions you tell your classes to perform. You need to define them inside the class, like so:

```
irb(main):021:0> class Kindle < Book
irb(main):022:1> def sayMotto
irb(main):023:2> puts "No more paper!!!"
irb(main):024:2> end
irb(main):025:1> end
=> :sayMotto

irb(main):026:0> new_kindle = Kindle.new
=> #<Kindle:0x007fcabc1630d0>
irb(main):027:0> new_kindle.sayMotto
No more paper!!!
=> nil
```

Look, we create a Kindle concept. Inside we use the *def* keyword to define a method. This method is called *sayMotto*. The body of this method tells it to print *No more paper!!!*. Notice that there are two *end* keywords. The first one to indicate we are done defining the method, the second is for the end of the class definition. Then, we can call our method by using its name on our newly created Kindle instance!


Okay, that's enough for one article. I feel like I've covered enough stuff for one article. I'll see you in the next one.

Have fun!