A Class in Ruby

Juzer Shakir
5 min readJul 4, 2021

--

A detailed overview of a class, its instance methods, variables, class eval, nested classes & class Inheritance.

Prerequisite

This topic will be easier to comprehend if you know the following:

Definition

A Class is a blueprint of an object. It’s methods and variables describe the features and behaviors of an object.

What is an object referred to here?
An ‘object’ refers to a class object or class instance. These are created when .new method is given to a class.

The following topics will be covered in this article.

Remember: in the above program, object is an instance of a class Demo and not a class itself!

“Hi”.is_a? String # => true
object.is_a? Class # => false
Demo.is_a? Class # => true

But why an instance and not a class?
As described earlier, a class is a characteristic representation of an object. Many objects can have similar characteristics, so instead of writing the same methods multiple times for each object, we group them as a class.
An example:

I am Juzer Shakir and I am not a robot!
I am Huzefa Biyawadwala and I am not a robot!

As shown in the above example, 2 objects were created of same class yet they hold different names but they share the same characteristic, name. And we can instantiate as many class objects as we want.

An initialize is a built-in method provided by Ruby. Can we write our own methods? Of-course!

Any classes created is an instance of a class Class, which is mother of all classes.

Methods

Methods provide functionality to a class object or to class itself.

Types of methods are Instance methods and Class methods.

Instance methods

Instance methods are methods that provide functionality and are accessible to class objects or instances of a class.

We initiated an instance method named age and takes an argument num. Its structure is very similar to initialize method we saw in the previous program and so will be every other method.

We first initiate a class object of Class Human and then call an instance method on it. Here the class objects, person_1 & person_2, actually have no idea that it has an instance method, age. When we call method age to class objects, person_1 or person_2, Ruby will find objects’ class, which is Human, and find the method age in it.

We provide an argument to a class object as the instance method age expects one and if we don’t provide an argument on call, it will raise an ArgumentError.

There’s also another way to initiate an instance method to class object by….

Class Eval

Class Eval is the ability to explicitly create an instance method outside the scope of the class.

And it's similar to this:

Haven't changed the method name and its output to keep things simple.

You can access these methods as you normally would with methods defined inside the class scope.

So why use class_eval & instance_eval anyways?

It's useful when the class you want to add the method to is not known to you until runtime! Yup, you read that right! This is a concept of meta-programming which is a completely different topic to be covered here, so let’s disregard it for now. But I hope you got the gist of it so if you encounter this in other programs or articles, you’re already well aware of it!

To get list of instance methods available of a class:

testing.methods # access instance methods through class object
Test.instance_methods # access instance methods through class
p Test.instance_methods(false)
# => [:normal_method, :classeval_method]

Next, let's take a look at:

Instance Variables

In my previous article, I went through what instance variables are.

And another article demonstrates how and why to use the Accessor method in Ruby.

Class methods

I have created a different article on this topic to cover it in a deep and detailed manner.

Constants in class

In my article Constants in Ruby, I have elaborated deeply on how it's defined, its scope in a program, and how it can be accessed.

Nested Classes

A class within a class:

Methods of Class Outer won't be available inside in any of the nested classes.

If constants are declared in class Outer then they will be available to any of the methods and classes defined in Outer class.

The ancestor chain shows that Inner class is a part of Outer class, meaning that Inner class is within the scope of Outer class and it shows that it descends from class Object.

We can access Class Inner as shown in line #8.

Class Inheritance

We have seen examples of class inheritance in the above programs many times with the help of ancestors method. Class Object and Class BasicObject were the ones that showed up every time.

Object.ancestors   # => [Object, Kernel, BasicObject]
# Kernel is a module and not a class...
Object.superclass # => BasicObject

So how does class Object make class BasicObject its parent class or how does class BasicObject make Class Object its child class? By < operator.

Let's see this process by giving our own different class names:

First, we declare Parent class and declare an instance method.

Then we declare a Child class followed by a < operator followed by class_name that it needs to descend from.

And when we give ancestors method to Child class in line #12 we see Child class is indeed now a child of Parent class or in other words it inherits from Parent class.

We have declared a method i_am in both classes. The super method in Child class calls the method with the same name it's declared in, i_am, to its parent class Parent. In our program, i_am method is called of Parent class by super method defined in Child class. If i_am method is not found in the Parent class, it would give NameError.

Methods of Parent class are available to Child class as it descends from it. So in Child class, we can re-declare the method that's already declared in its Parent class to override its logic.

Just as methods, Constants of Parent classes can also be accessed by the child class.

My previous article: Strings & Symbols in Ruby
My next article: Modules in Ruby

--

--