Skip to content

Classes

Last updated on July 28th, 2024 at 05:44 pm

Table of Contents

Because Ruby treats everything as an object and objects are derived from classes, it makes sense that one of the first things you should know is how to create your own classes.

Defining a Class

For the purpose of clarity, it is always suggested that a class be named in a manner that suggests its purpose and the name be in CamelCase. Declaring a class is quite simple:

As with all other object oriented languages, Ruby classes can inherit from other classes.

While Ruby does not have the ability to inherit from multiple classes, known as multiple inheritance, a class can include modules through what is called “MIXIN” functionality.

What’s the difference between classes and modules? Classes can be defined repeatedly and expanded upon, whereas a module can only be defined once. As well, a module cannot be instantiated, whereas a class must be instantiated to be used. As well, you cannot inherit from one module to another. Instead, you would need to include the desired module into your new module.

If you ever want to know what a class is derived from, you can use the ancestors method.

Extending Existing Classes

One of the more dangerous aspects of Ruby is that you can easily extend any class. Why is this dangerous? It allows you to overwrite methods that are already defined and it won’t tell you when this happens.

Extending a class is as simple as declaring the class without inheritance.

Class Initializers

It is very common in object oriented programming languages that a class has a default method that is executed when the class is instantiated. This is accomplished by having a method by the name initialize, which can take parameters if required.

Unlike some other object oriented programming languages which allow for overloading the initializer, Ruby only allows a single initialization method.

Instantiating the class

To use a class, it must be instantiated. This is done with the new method.

If the class has an initializer that requires parameters, simply provide those values when the object is instantiated.

Class Variables

Earlier in this guide we covered the topic of class variables. Here, we will expand on the topic a bit.

A class variable can be defined in any class method and will be specific to an object for the life of the object. Normally, a class variable will not exist until it is used. It is possible, however, to define class variables in a static manner and also to provide getter and setter routines for those variables.

In Ruby the class variable is called an attribute. There are four methods that are used for defining attributes – attr, attr_reader, attr_writer, and attr_accessor.

Both the attr and attr_reader methods create an instance variable and a getter method for each attribute name passed as argument. An argument can be a Symbol or a String that will be converted to Symbol

This is the equivalent of making the variable read-only outside of the class. You can modify the variable as a class variable in any of your class methods, but the variable can only be read from class instances.

The attr_writer method creates a setter method for the variable, but not a getter method.

The attr_accessor method will create both getters and setters for each variable defined.

Using super

Every Class you define will have an inheritance chain that you can see with the ancestors method. You can extend an ancestor’s methods by redefining them and then using super to call them from within the new methods.

What methods can my object access?

Sometimes it is helpful to get a list of which methods an object will respond to. This can be determined by applying the method methods to the object. As you can see in the screen shot below, the output isn’t terribly readable.

You can quickly see that any class you define will automatically inherit methods that are common to all classes .

Additionally, on rare occasions it is helpful to know if an object has a given method. This can be determined with the respond_to? method.

As well, sometimes you might want to know the class name of a given object, which can easily be determined with the methods “class.name”. You if you leave the method name off, class will respond with the class of the object, as an object itself.

Helper Classes

It is not uncommon that you will run into situations where a method can and should be shared amongst more than one class. Ruby uses Helper Classes to house these methods. Have a quick look at this page on Ruby Guides for a little more detail.

Aborting Program Execution

Typically, you will want a program to execute to completion. However, there are instances where you will want to exit the program early. The statements available to you for this are raise, exit, exit!, abort and fail.

The raise statement is used to create an exception, which I will cover in greater detail in the Exception Handling section of this guide. At this point it suffices to say that the raise statement will terminate the application and can be issued alone on a line, or it can be issued with arguments, these being the error that is being raised, a text message that explains the exception being raised and the caller. If you raise without any arguments, it will create a RuntimeError exception.

The exit statement is actually an alias for the raise statement and raises the exception SystemExit. Just prior to termination, Ruby executes any at_exit methods and runs any object finalizers.

The exit! statement will exit the application immediately and not run any exit handlers. If you provide it a parameter it will be passed on to the underlying system as the exit status.

The abort statement will terminate execution immediately and, if provided a message, this message will be written to STDERR prior to terminating.

The fail statement is an alias for raise.