Defining Instance Methods
Learn to define instance methods in Ruby.
We'll cover the following
Methods can be defined and called on objects, like 1.odd?
. They can also be defined in classes, like Calculator.new
.
Methods that are available in classes are called class methods, and methods that are available on instances are called instance methods.
In this lesson, we want to add the stand-alone methods that we’ve learned about previously to our Calculator class so that they’ll end up as instance methods.
Here’s how we can do that:
class Calculatordef sum(number, other)number + otherendend
We simply move the method into the class body so that it’s enclosed by it.
Remember: Instance methods are defined inside the class body.
Note also that the method definition is indented by one level, that is, two spaces. This signals that the sum
method belongs to the Calculator
class. Everything between the class Calculator
line and the final line, end
, is called the class body. Just like method bodies, we indent them by one more level.
Note: The
class
andend
keywords sit on the same level. The class body is indented by one level.
How can we call the sum
method on a calculator?
Before you read more, think about this a little. In theory, you have all the knowledge you need to answer this question:
-
We’ve learned how to create a new calculator instance (object).
-
We’ve learned how to call a method on an object.
-
We’ve learned how to pass arguments (extra bits of information) to the method call.
We can instantiate (create) a new instance from our Calculator
class and call the sum
method on it, like so:
calculator = Calculator.newputs calculator.sum(2, 3)
This outputs 5
. Success!
A calculator that can’t do anything but addition is rather useless. Let’s develop our class by adding more operations or methods. Let’s also rename sum
to plus
so that it matches the operator:
class Calculatordef plus(number, other)number + otherenddef minus(number, other)number - otherenddef multiply(number, other)number * otherenddef divide(number, other)number / otherendend
Now, our calculator is slightly more useful. We can do the most basic math operations with it.
calculator = Calculator.newputs calculator.plus(2, 3)puts calculator.minus(2, 3)puts calculator.multiply(2, 3)puts calculator.divide(2, 3)
This outputs:
5
-1
6
0
This looks all good except for the last line, right? That’s because dividing one integer by another returns an integer.
We could require that the calculator’s user pass (provide) the appropriate types of numbers themselves. It would be their own responsibility if something goes wrong with the division.
However, our calculator should be smart enough to notice this.
Make it smart
We could improve our calculator by always changing the type of the numbers passed to the divide
method. In other words, the divide
method would take the numbers, make sure at least one of them is a Float
(floating point number), and only then do the calculation.
The method used to convert an integer to a float is to_f
. When called on a float, it just returns the float:
puts 1.to_fputs 1.0.to_f
Let’s use that knowledge to improve our divide
method. It’s sufficient to call the to_f
method on one of the numbers because that ensures we get a float back:
class Calculator# ...def divide(number, other)number.to_f / otherendend
With that in place, our calculator always returns a Float
from the divide
method:
calculator = Calculator.newputs calculator.plus(2, 3)puts calculator.minus(2, 3)puts calculator.multiply(2, 3)puts calculator.divide(2, 3)
This outputs:
5
-1
6
0.666666666666
Perfect.