Object Architecture in Ruby Explained

Inheritance, Supers and Modules

Rukshan Uddin
4 min readNov 22, 2019

Everything in Ruby is an object. As everything is an object, there are basic rules that every object will follow. All objects can inherit from another object. All objects can modify methods that are inherited

Inheritance

What is inheritance?

If we look at the dictionary definition of inheritance, in other words, we see that it would refer to something received from someone else.

Bus drivers, ambulance and taxi cab drivers all share common behavior in that they navigate the roadways, but they are different from each other and each have their unique qualities that make them different from each other. We could say that they all inherit driving skills that come from just a basic drivers license. They are all different kinds of drivers. You could even say, different classes of drivers.

Photo by Fabian Grohs on Unsplash

In the world of Ruby, inheritance refers to being able to create classes with common behavior, while still differentiating those classes.

For our example, with inheritance, we could inherit the BusDriver, AmbulanceDriver and TaxicabDriver classes from a Driver class. Then, any changes made to the Driver class would apply to the other class. In the Driver class we could have the basic skills that come with having a drivers license: stopping, taking turns, reverse, etc. All our other classes could inherit those things that the Driver does.

AmbulanceDriver < DriverBusDriver < DriverTaxicabDriver < DriverDriver.turn, Driver.reverse, Driver.stop ….

We could have class methods for all those things that the Driver does. So since each of our other classes inherit from the Driver class, we could do use any of our methods that our Driver class could, with any of the classes that inherited from the Driver class. i.e:

AmbulanceDriver.turnTaxicabDriver.reverseBusDriver.stop

Super

Photo by Yogi Purnama on Unsplash

What is a super? What is the super keyword? Let’s take our example of drivers from before. We have a parent, Driver class, that our TaxicabDriver, BusDriverand AmbulanceDriver classes inherit from.

Let’s imagine our Driver class has a method, valid_license, that sets an instance variable, @valid_license equal to true.

class Driver  def valid_license    @valid_license = true  endend

A taxicab driver would need to have a valid license as well. But in addition to a normal license, they need a chauffeur’s license. Since we inherited the valid_license method all we would need to do is add in anything that is added to the code. i.e:

class TaxicabDriver < Driver  def valid_license

super
@chauffeurs_license = true endend

In my example, the TaxicabDriver inherits the valid_license method and uses super to add the fact we are setting the instance variable of chauffeurs_license to true. Real-world example would be that a taxicab driver has both a driver’s license and a chauffeur’s license. He has everything a normal driver has, but has a extra things that only taxicab drivers have.

Modules

A module to put it simply, can be a set of methods that don’t necessarily respond to a hierarchical order. Let’s look back at our real-world examples. All our drivers inherited from the Driver class because they were all types of drivers.

Let’s expand on that.

Photo by George Huffman on Unsplash

Let’s talk about the rules of the roads.

Not only do drivers have to follow them, pedestrians, motorcyclists and bicyclists all would to follow the same rules. We could say in Ruby they would have methods that would be shared. We could put these in a module to use inside the respective classes.

(psuedocode warning)

For example:

module RoadRules  def traffic_lights(color)
if color == "red"
stop
elsif color == "yellow"
go if @traffic == "clear"
elsif color == "green"
go
end
end
def go
move_forward
end
def stop
stay_in_place
end
end

Now this is a mix of pseudocode and actual code to explain certain parts, we would have to go more in-depth to get everything to actually work (the go and stop methods don’t do anything in Ruby, they are just examples of what we would expect Drivers and Pedestrians to do), but this is basically what we could want our module to do. Any one of our classes of people that use the road (Driver, Motorcyclist, Pedestrian, etc.) could include this module in their class to be able to use the “RoadRules”. It doesn’t make our Motorcyclist a Driver or our Pedestrian a Cyclist. All it does create a module of “RoadRules” that can be included in any class.

class Pedestrian    include RoadRulesendclass Driver    include RoadRulesend

In the example above, both Pedestrians and Drivers include the RoadRules module, meaning that both Pedestrians and Drivers can use methods defined in RoadRules, without having a direct connection to each other. There is no hierarchical order, they are only linked because of their shared module, “RoadRules” and can all use the methods contained within that module. A Pedestrian is not a Driver, but they both can follow rules of the road.

(This piece is a work in progress. I am a student at Flatiron School and this is my first attempt at a technical blog post. This will be edited. The posts will get better. If you have any suggestions please drop me a line on twitter @RukshanUddin)

--

--