Object-Oriented Programming with Ruby pt. 1

I had OOP in my college last year and it was a bummer. Looking back, I may have learned the most valuable skill for developers: being a developer == a full-time self-learner (a new concept that I just invented).

But since I quit college and started my internship last year, I felt the need to go back to the basics and finally be able to write good code using OOP fundamentals. I started a Rails tutorial and I noticed that I have never run a Ruby program (without rails) on my terminal!

What I learned most from this experience was that I should focus on learning the foundations before the frameworks, for example: learn Ruby before Ruby on Rails. I wanted to understand why Ruby became so popular and what makes OOP a paradigm so important in Computer Science.

I found a lot of resources online and one of them is the MIT Computer Science which offers a complete Introduction to Computer Science and Programming with Python and I decided to make some notes about it but in Ruby. OOP is given in lectures 14, 15 and 16 if you want to give it a try too. Also found the Docs — Programming Ruby which is a complete material to follow. Both these materials helped me study and are guiding this post 🙂

This is the part one, which will be an introduction to OOP introductory concepts, like Class and Objects. I also started a repository on GitHub where I apply what I am studying to keep a record.

Abstract everything

OOP is not a new concept in Computer Science, but it became very popular only on the 70’s. But why do we need OOP and why did it become so popular? Quoting Prof. Eric Grimson:

Object Oriented Programming is great when you are trying to model systems that consist of a large number of units that interact in various ways.

That’s why OOP is so vastly used and solves a huge amount of problems in our real life because we can solve almost every problem with this paradigm! By gathering together some data it allows you to write better code, which means it is easier to test and to refactor.

we are all objects

Let’s go back to the basics

Everyone who starts to study OOP start to hear a lot about ClassesObjects, and Instances. Let’s explore them a little theoretically.

Classes, Objects, Instances

You must have heard that in Ruby, everything is an object: a Class is an Object; An Instance is an Object and an Object is… I think you get the idea! Although in our real world we deal with lots of objects, it’s hard to abstract it to code — at least for me. But once we understand the purpose of it and the concepts behind it, it starts to make more sense and things start to get easier #hopefully.

A Class is a collection of data and functions that make sense to stay together because they have characteristics in common. It helps your daily work by preventing you from spreading pieces of code through different files.

As prof. Eric Grimson said in one of his classes, it’s easier if think of a Class like a stamp: you can print several objects of a Class using its stamp. Every new object created using a stamp will have the same characteristics but they will still be different objects because they are unique copies of that stamp, they’re randomly allocated in different locations in memory.

And why are objects so useful? Because we can manipulate them as we need! What would be of the human race without manipulating everything around, right?!

But how does that Class definition is applied to Objects? Well, when you create a new object it comes with some data. You are instantiating a new Object from a specific Class. You can call this object’s data as attributes. You can define them in your initialize method (a special Class method), for example.

You can really manipulate them to your needs with the functions associated with its Class. You can call them instance methods. Now let’s create a simple Class to see this in action.

So instance and objects are pretty much the same, it’s up to you how you wanna call it 🙂

Show me the code

We are going to create animal instances from the Animal Class (you can also see the code on GitHub). But before diving into the code, let’s think about the implementation a little. Let’s say we need to create an Animal Class so it’s easier to create a lot of cute animals to play with.

What does an animal have? What does it do? (We don’t need to think about everything now, we can always add/remove any information about our classes whenever we want).

We know that animals have a name, an age, a weight and a date of vaccination. These are the attributes. We also know that animals need annual vaccination, sleeping and playing. These are the object/instance methods. We’ll write a method to check if the animal has taken its vaccines, so if a new animal with outdated vaccination is created, we’ll get an alert.

We can put this into a file called animal.rb:

class Animal
  # The initialize method is a special Class method.
  def initialize(name:, age:, weight:, last_vaccine_year:)
    @name = name
    @age = age
    @weight = weight
    @last_vaccine_year = last_vaccine_year
  end

  def is_vaccinated?
     current_year = Time.now.year
     return true if current_year - last_vaccine_year <= 1
     "#{name} has not been vaccinated this year yet"
  end
end

What’s next

This simple Animal Class works fine, but it’s pretty generic, don’t you think?. What if I want to have cats, dogs, birds, fishes, horses…? I am going to need to think of Classes like Species in Biology… cool, right? But that will be our next subject when we will discuss Inheritance and Encapsulation.

If you have any questions or want to suggest/contribute feel free to comment here. I am learning Ruby as well, so any suggestion is welcome. See you soon!