GSwR VI: Stay Classy with Ruby
Welcome to the last post in the Getting Started with Ruby series.
In the previous post, we covered writing our own methods. In this post, we’ll learn all about how classes work: How to create them, how to create methods for them, and how to use inheritence to save recreating lots of behaviour.
Classes are quite literally the building blocks of Ruby – everything in Ruby is an object and classes are basically a list of method definitions that acts like a blueprint for objects. Classes are used to create objects, known as instances of the class. These objects have all of the methods defined in the class.
We’re going to start by looking at how to add our own methods to the built in classes such as Strings, Integers and Arrays.
Changing Built In Classes
We’ve already seen many of the built-in methods in classes like
Integer, such as
odd?. Ruby let’s us add extra methods to these classes by opening up the class definition. This is done by typing the keyword
class followed by the name of the class.
Here’s an example of opening up the
Integer class to add a new method called
class Integer def double self * 2 end end
Notice that the word ‘Integer’ starts with a capital letter, which is true for all class names.
This new method returns the value of the integer that calls the method multiplied by 2. The
self keyword refers to the object itself, in this case the integer that calls the method. Now all integers will have this method.
We can test this code out in IRB. First of all, save the code above in a file called ‘extensions.rb’ and then load it into IRB so that the extra methods become available to us. To do this, navigate to the folder where the ‘extensions.rb’ file is saved and then launch IRB by typing
irb into a terminal prompt. Once IRB starts, we just need to type the following:
load ‘./extensions.rb’ => true
Now we can have a go at testing out our new method:
2.double => 4 5.double => 10 12345.double => 24690
Great, it works!
You can add new methods for all of the built in classes such as Strings and Arrays. In fact you can even redefine the methods that already exist. Here’s an example that changes the behaviour of the
reverse method on the
String class. Add the following code to the bottom of the ‘extensions.rb’ file:
class String def reverse "no reversing" end end
As you can see, by opening up the String class we redefine the
reverse method to return a string that says ‘no reversing’. Have a go at running this in IRB – you will need to save ‘extensions.rb’ and then
load it again for the changes to take effect.
Changing the way built-in methods behave is very much frowned upon since people expect methods to work in a certain way. Adding new methods that add more functionality is (usually) thought of as good thing though. This is as monkey patching. Ruby on Rails has a module called Active Support which adds lots of extra methods to the
String class. One of the new methods is called
pluralize, which returns the plural version of a string.
Here’s an example of a similar
pluralize method. Add it to the bottom of the ‘extensions.rb’ file:
class String def pluralize case self when "woman" then "women" when "person" then "people" when "octopus" then "octopi" when "sheep" then "sheep" else self + "s" end end end
This uses a case statement to return the plural of some irregular words and then just puts an ‘s’ on the end for all the rest. Let’s have a look at this in action in IRB (don’t forget that you’ll need to load extensions.rb again):
octupus.pluralize => octupi book.pluralize => books bus.pluralize => buss
It’s by no means complete, as shown in the last example. It’s readily apparent, though, how this could be used to add some very useful functionality to all strings.
Creating Your Own Classes
We don’t just have to make do with playing around with the built in classes though – we can create our own!
In the last few posts, we’ve imitated a die being rolled. Let’s create a
Die class that can be used to create lots of die objects. We can then “roll” these dice produce random numbers.
Create a file caled dice.rb and add the following code:
class Die def roll rand(1..6) end end
Any class starts with the
class keyword and is followed by the name of the class (always capitialized). It ends with the
end keyword. We then add any methods inside this class definition.
To create a new
Die object, we use the
new method of the
Die class (don’t forget to load the ‘die.rb’ file):
die = Die.new => #<Die:0x8e3459c>
This instantiates a new Die object represented by