Instance Variables Are the Opiate of the Classes
Technical Blog 5: Classes in Ruby
This week at DBC, we’ve delved deep into the world of Ruby Classes. For the uninitiated, Classes in Ruby are like blueprints for creating objects and methods. If you have a Class that contains a set of methods, you can run that class over and over again and get slightly different results based on the rules you provide every time you run an instance of that Class. If none of that makes any sense, don’t worry. Today I’m here to show you what a Ruby Class would look like if we created one in the real world.
For those of you who aren’t already aware, my wife and I are expecting our second child. Like, any minute now. I have to keep my phone on me at all times in case she goes into labor while I’m not at home. Any texts or calls during the day cause my heart to start racing. The car is constantly filled with gas so we don’t inadvertently run out while on the way to the hospital. Of course, this isn’t our first rodeo. We already have a son who just turned 2.
So, I thought it would be fun and not at all inappropriate for me to turn my very pregnant wife into a Class and turn my son and soon-to-be daughter into Classes that can inherit from Mommy class. Here we go:
When you create a Class, you’re creating an object, since almost everything in Ruby is an object. There’s a whole lot that goes into rules for objects in Ruby, but in the case of Classes, all you need to know is that we can create a new Class in much the same way that we create objects like Arrays and Hashes.
That’s it. You’ve created a Class. Right now, though, It’s not a very interesting Class, and it won’t have any effect on anything inside or outside of itself, but it exists and that’s all that matters. When you create a Class in Ruby, it’s common practice to capitalize the Class name, in this case ‘Mommy’. Let’s see if we can expand on what defines Mommy:
So what’s happening here? Essentially, we’ve created the blueprint for some of the attributes that define my wife. Really, though, we’ve created the blueprint for attributes that could potentially define anyone. That’s the beauty of Classes. Once you create the skeleton, Classes are infinitely adjustable, all depending on what you input. Every time you create a new instance of ‘Mommy’, she can be different in every way. Let’s try it out:
So we’ve created an instance of the ‘Mommy’ Class called ‘pregnant_steph’. In this state, she has certain attributes that make her unique, but there are also several details she shares with other instances, which we’ll see here:
As we can see, by slightly modifying the details of the instance of the ‘Mommy’ Class, we come up with a somewhat different (and infinitely more comfortable) instance.
Another great function of Classes is their ability to pass down their methods, functions, definitions, etc., to other Classes. This is called inheritance and it means smaller classes can have access to the powerful tools of their parent Class, also known as a Super Class. Let’s use another real world example by turning my children into Sub-Classes of the ‘Mommy’ Class:
Once again, I’ve created an empty Class, but this time, there’s something different. Since we’ve defined ‘Baby’ as being a Sub-Class of ‘Mommy’ using the < symbol, we now have access to all of the capabilities that ‘Mommy’ provides, but inside ‘Baby’. If I wanted to put name, height, weight, hair, eyes, etc., inside the ‘Baby’ Class, I wouldn’t need to define those objects again, since they already exist in ‘Mommy’. Let’s make ‘Baby’ a little more interesting:
At the top of this Class creation, right underneath Baby < Mommy, you’ll see something called attr_accessor. This is one way to list out what data we plan to use during the Class creation. You’ll notice that even though we ask for first_name, last_name, hobbies, tv_shows, etc., in the ‘initialize’ method, we haven’t listed these as required in the attr_accessor. This is because the ‘Mommy’ Class already has these items, and since ‘Baby’ inherits from ‘Mommy’, it has access to its methods as well.
Of course, one thing you have to be careful of when creating Class instances is to provide all of the required information. If you leave something blank, it will spit out an ArgumentError, which essentially means you didn’t provide enough arguments, or data requirements.
Creating the robin instance will return an error because we didn’t provide enough arguments to match what is required. We have name, age, hair, eyes, and hobbies, but then we skipped the favorite books and favorite TV shows, and so we get an error. Even if we don’t know the answer to the required argument, providing the proper number of arguments means the code will at least run, even if it looks incorrect.
So that’s Classes! And that’s it for this week’s Tech Blog. My name is Edwin Unger, and I’m a web developer. Sort of.