📄 Table of Contents

Introduction / History

Ruby is a “dynamic, open source programming language with a focus on simplicity and productivity. It has an elegant syntax that is natural to read and easy to write.” created by Matz.

Why Ruby ?

For me the first reason to learn Ruby was that it is, in fact, a beautiful programming language. It is really natural to code it and always express my thoughts.

The second main reason was Rails. The well known framework that Twitter, Basecamp, Airbnb, Github, and so many companies use.

How do I run a Ruby file?

It’s easy — just create a file with the extension . rb , navigate to that file’s directory from the command line, and run it using $ ruby filename. rb (the dollar sign is just the command prompt). You’ll be able to gets from and puts to the command line now!

Requiring Scripts or Gems in IRB

If you want to include a gem file (a library of methods, for instance) or another Ruby script in your IRB session, use require. require will search for any gems you've downloaded from the internet. If you've explicitly provided a path to be required, for instance ./my_script.rb, it will bring in that specific file instead.

Once it’s been required, you can run methods and access variables from that file in IRB.

Load vs Require

There’s another method load which is almost identical to require but allows a file to be loaded multiple times.

This can be handy in IRB if you’re developing a script and want to make changes to it before reloading again without having to completely quit out of IRB. require only allows you to load the file once and will not work if you try to do it again:

While load is handy when you're playing around with command line scripts because it saves you from quitting IRB to refresh your changes, you should stick with require if you use this functionality in your own scripts. That's because require makes sure you've only loaded the file once while, with load you might have accidental double-or-triple loads if multiple files require each other.

In Ruby, we have

You are maybe asking what is the difference of “each” iterator and so well known “for” looping. The main difference is that “each” iterator maintain the variable only inside of scope. “for” looping keeps the variable live outside the block. Let’s do a test:

The variable “num” in the “for” looping will keep alive after iteration block. “num” variable from “each” iterator block will not.

one = 1
my_name = "anil kumar"
male = true
my_integers = [1, 2, 3, 4, 5]

Arrays has a concept called index. The first element gets the index 0 (zero). The second gets 1, and so on. You got the idea!

The most common methods to add a new value to an Array is push and <<.

bookshelf = []
bookshelf.push(“The Effective Engineer”)
bookshelf << "Lean Startup"

You may ask “But it doesn’t use the dot notation as other methods. How it could be a method as well?” Wow, nice question! :)

Writing this:

bookshelf << "Hooked"

..is similar to writing this:

bookshelf.<<("Hooked")

Hash: Key-Value Data Structure | Dictionary Collection

Classes & Objects

let’s understand Ruby syntax for classes:

class Vehicle
end

And objects are instances of a class. We create an instance by calling .newmethod.

vehicle = Vehicle.new

Now, vehicle is an object (or instance) of the class Vehicle.

Remember that our Vehicle class has 4 attributes: Number of wheels, type of tank, seating capacity and maximum velocity. We set all this attributeswhen creating a vehicle object. So here we define our class to receive data when instantiates it.

We use the initialize method. We call it a constructor method. So when create the vehicle object, we can define this attributes, as below:

tesla_model_s = Vehicle.new(4, 'electric', 5, 250)tesla_model_s
# => <Vehicle:0x0055d516903a08 @number_of_wheels=4, @type_of_tank="electric", @seating_capacity=5, @maximum_velocity=250>

All attributes set. But how can we access this attributes values? We send a message to the object asking about them. We call it a method. It’s the object’s behavior. Let’s implement it!

This is an implementation of two methods: number_of_wheels and set_number_of_wheels. We call it getter & setter. Because the first get the attribute value, and the second set a new value for the attribute.

In Ruby, we can do that without this methods. It is the attr_reader, attr_writer and attr_accessor. Let’s see it with code!

So for now we learnt how to get attributes values, implement getter and setter methods & use attr (reader, writer and accessor).

But we can also use methods to other things like “make_noise” method. Let’s see it!

When we call this method, it just returns a string “VRRRRUUUUM”.

Encapsulation: hiding information

Encapsulation is used as a mechanism to restrict direct access to objects’ data and methods. But the same time it facilitates operation on that data (objects’ methods).

Encapsulation can be used to hide data members and members function.Under this definition, encapsulation means that the internal representation of an object is generally hidden from view outside of the object’s definition. — Wikipedia

So all internal representation of an object is hidden from the outside, only the object can interact with its internal data.

In Ruby we use methods to direct access data. Let’s see an example:

We just implemented this Person class. And as we know to create the object person, we use the new method and pass the parameters.

tk = Person.new("Leandro Tk", 24)

So I created me! :) The tk object! Passing my name and my age. But how can I access this information? My first attempt is to call name or age method.

We can’t do it! We didn’t implement the name (and the age) method. Remember when I said that “In Ruby we use methods to direct access data”? To access the tk name and age we need to implement those methods on our Person class.

Now we can direct access this information. With encapsulation we can ensure that the object (tk in this case) is the only responsible to access the data (name and age). The internal representation of the object is hidden from the outside.

Inheritance: behaviors and characteristics

In object oriented programming, classes can inherit common characteristics (data) and behavior (methods) from another class.

Let’s see another example and implement it in Ruby!

Imagine a car. Number of wheels, seating capacity and maximum velocity are all attributes of a car. We can say that an ElectricCar class inherits these same attributes from Car class.

Our Car class implemented! :)

Instantiated and we can use all methods created! Nice!

In Ruby, we use the < operator to a class inherits from another. An ElectricCar class can inherits from our Car class.

Simple as that! We don’t need to implement the initialize method and any other method, because this class already has it (inherited from Car class). Let’s prove it!

Beautiful!

Module

Define a Module

In Ruby, the module keyword allows you to define a new module

Greeting -> This is module name

hello -> this is a method name

Modules have 2 main purposes:

Module as namespace

Namespacing is a way of bundling logically related objects together.

Modules serve as a convenient tool for this. This allows classes or modules with conflicting names to co-exist while avoiding collisions.

A good example of namespacing is the Rails module.

This module contains a bunch of classes and modules — For example, the Rails::Application class

Here we can see that the Application class is defined within the scope of the Rails module.

Note that to access this class from outside of the module Rails, we use the :: syntax.

As the Application class is a pretty common class name that we could encounter in another gem then — and in order to avoid clashing — the Application class is encapsulated in the Rails module.

This means that the Rails::Application class will never clash with an Application class or a Dummy::Application class that can be defined anywhere else.

Composition with the mixin facility

Ruby doesn’t handle multiple inheritance.

So how to organise a class to keep it maintainable in long term ?

The answer is by applying the Composition over Inheritance principle.

The Composition principle is based on the fact that a class should contain a set of objects that provide the desired functionality.

So instead of passing the functionality using the inheritance chain, it’s preferable to compose a class of objects that are responsible of providing the desired functionality.

Actually, Ruby facilitates the use of composition by using the mixin facility.

Indeed, a module can be included in another module or class by using the include, prepend and extend keywords.

For more read at @ https://medium.com/rubycademy/modules-in-ruby-part-i-a2cdfaccdb6e

in-built module(s)

An example of Ruby module is Math module. We can access the constant PI:

Math::PI # > 3.141592653589793

And .sqrt method:

Math.sqrt(9) # 3.0

How can we implement our own module and use it in classes ?

Experience with Front-end Technologies and MERN / MEAN Stack. Working on all Major UI Frameworks like React, Angular.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store