DEV Community

Cover image for Learning Ruby: Playing with irb
Damien Cosset
Damien Cosset

Posted on

Learning Ruby: Playing with irb

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]
Enter fullscreen mode Exit fullscreen mode

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

➜  ~ git:(master) ✗ irb
irb(main):001:0>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>'
Enter fullscreen mode Exit fullscreen mode

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>'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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>'
Enter fullscreen mode Exit fullscreen mode

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>'
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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!

Top comments (2)

Collapse
 
defman profile image
Sergey Kislyakov

And there's pry, which is irb on steroids. I was using it as long as I remember myself as a Ruby developer.

Collapse
 
damcosset profile image
Damien Cosset

Will try! :)