Ruby Class Methods

What they are and when to use them

If you're reading this post, you're probably familiar with Ruby classes; they're a fundamental part of designing object-oriented programs and are a very convenient and powerful way to store data and functionality for objects. Last week I covered some basics about classes and methods. This week I'm going to go more in-depth about class methods: how they differ from instance methods and when and how to use them.

Class Methods vs. Instance Methods

The difference looks very subtle in the actual code but is significantly different in execution. Take a look at the code below:

class newClass
def self.classMethod
puts "Class method"
end

def instanceMethod
puts "Instance method"
end
end

Did you spot the difference? Class methods are called on the class, or self. This means that this method can be used on all instances of this class.

The instance method, however, is called on an instance of that class, meaning it can't be called without a new or existing instance of that class. Take a look at the code below to see what happens:

class NewClass
def self.classMethod
puts "Class method"
end

def instanceMethod
puts "Instance method"
end
end

NewClass.classMethod #-> "Class method"
NewClass.instanceMethod #-> NoMethodError: undefined method 'instanceMethod' for NewClass:Class
NewClass.new.instanceMethod #-> "Instance method"
NewClass.new.classMethod #-> NoMethodError: undefined method 'classMethod' for #NewClass:0x1e820

We called a class method on our class, which worked perfectly. However, when we tried to call an instance method on the class, we weren't so lucky.

We saw similar results when defining a new instance of our class and calling methods on it. We were able to get the instance method to work but were unable to call the class method on it.

When to use class methods

As a very broad and general rule, class methods are used when you aren't dealing with anything specific to an instance. So if we use last week's basketball teams as an example, you could write a class method that defines the makeup of a starting lineup: point guard, shooting guard, small forward, forward and center. These are universal in every instance of the basketball team class, so we could define it at the class level.

class BasketballTeam
def self.positions
puts "Point guard, shooting guard, small forward, forward, center"
end
end

BasketballTeam.positions #-> Point guard, shooting guard, small forward, forward, center

When to use instance methods

Instance methods, then, are used when data varies from instance to instance. In the basketball example, this would be player names, numbers, etc.

class BasketballTeam
def self.positions
puts "Point guard, shooting guard, small forward, forward, center"
end
def initialize(pg, sg, sf, f, c)
@pg = pg
@sg = sg
@sf = sf
@f = f
@c = c
end

def point_guard
puts "#{@pg}"
end

def shooting_guard
puts "#{@sg}"
end

def small_forward
puts "#{@sf}"
end

def forward
puts "#{@f}"
end

def center
puts "#{@c}"
end

def starters
puts "Point Guard: #{point_guard}\n Shooting Guard: #{shooting_guard}\n Small Forward: #{small_forward}\n Forward: #{forward}\n Center: #{center}"
end
end

MSU = BasketballTeam.new("Keith Appling", "Gary Harris", "Denzel Valentine", "Branden Dawson", "Adreian Payne")

MSU.starters #->
Point Guard: Keith Appling
Shooting Guard: Gary Harris
Small Forward: Denzel Valentine
Forward: Branden Dawson
Center: Adreian Payne

Take me back >>