# Why, or when to, use a class method?

**URL:** <https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875>\
**Category:** Ruby\
**Created:** [October 31, 2007, 9:28pm UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875 "2007-10-31T21:28:12Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [October 31, 2007, 9:28pm UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/1 "2007-10-31T21:28:12Z")

</div>

Here’s the example:

Jukeboxes charge money for each song played, not by the minute. That  
makes short songs more profitable than long ones. We may want to  
prevent songs that take too long from being available on the SongList.  
We could define a class method in SongList that checked to see if a  
particular song exceeded the limit. We’ll set this limit using a class  
constant, which is simply a constant (remember constants? they start  
with an uppercase letter) that is initialized in the class body.

class SongList  
MaxTime = 5\*60 # 5 minutes  
def SongList.isTooLong(aSong)  
return aSong.duration \> MaxTime  
end  
end  
song1 = Song.new(“Bicylops”, “Fleck”, 260)  
SongList.isTooLong(song1) » false  
song2 = Song.new(“The Calling”, “Santana”, 468)  
SongList.isTooLong(song2) » true

[http://www.ruby-doc.org/docs/ProgrammingRuby/](http://www.ruby-doc.org/docs/ProgrammingRuby/)

Because the definition is declared with “def  
SongList.isTooLong(aSong)”, this indicates it to be a class variable  
for the SongList class, ok so far. Why a class variable? All  
SongList objects will use the same method, but wouldn’t they use the  
same method even if it were an instance method? Methods are declared  
on the class, not the instance.

The class variable makes more sense to me, I can see the need better:

"For example, our jukebox may want to record how many times each  
particular song has been played. This count would probably be an  
instance variable of the Song object. When a song is played, the value  
in the instance is incremented. But say we also want to know how many  
songs have been played in total. We could do this by searching for all  
the Song objects and adding up their counts, or we could risk  
excommunication from the Church of Good Design and use a global  
variable. Instead, we’ll use a class variable.

class Song  
@@plays = 0  
def initialize(name, artist, duration)  
@name = name  
@artist = artist  
@duration = duration  
@plays = 0  
end  
def play  
@plays += 1  
@@plays += 1  
“This song: #@plays plays. Total #@@plays plays.”  
end  
end"

There is one @plays per instance, but only one @@plays which all Song  
objects share; this I follow.

Why use a class method in the first example, though?

thanks,

Thufir

---

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [October 31, 2007, 9:42pm UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/2 "2007-10-31T21:42:15Z")

</div>

Hi –

On Thu, 1 Nov 2007, Thufir wrote:

> Because the definition is declared with “def  
> SongList.isTooLong(aSong)”, this indicates it to be a class variable  
> for the SongList class, ok so far.

It declares it to be a class _method_. It may or may not use a class  
variable (actually the example you gave does not).

> Why a class variable? All  
> SongList objects will use the same method, but wouldn’t they use the  
> same method even if it were an instance method? Methods are declared  
> on the class, not the instance.
> 
> There is one @plays per instance, but only one @@plays which all Song  
> objects share; this I follow.
> 
> Why use a class method in the first example, though?

Typically, a class method is used when you have a method that’s  
directly related to the objects you’re using the class to represent,  
but that does something at a more general level than a specific  
object.

For example, let’s say you have a Car class. You want to create  
individual cars:

c = Car.new

and do things with them:

c.fill\_with\_fuel  
c.drive(120)

However, you might also want to do things at a more general level that  
still have to do with cars. For example:

class Car  
def self.brands  
[“Ford”, “Honda”, “Toyota”, “Volvo” …]  
end  
end

This provides a list of all car brands. I’ve made it a class method  
because while every individual car may be of a particular brand, I  
don’t expect every car to know about every brand. The Car class,  
however, is a good place to put general, high-level information about  
cars, like a list of all brands.

David

---

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [November 1, 2007, 12:30am UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/3 "2007-11-01T00:30:37Z")

</div>

On Oct 31, 2:17 pm, 7stud – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
[…]

> > Why use a class method in the first example, though?
> 
> So that you can check whether a Song is too long without having to  
> create a SongList object:  
> […]

What would be a case where there’s a SongList object, though? Or, if  
there are class methods then generally there won’t be objects of that  
class?

-Thufir

---

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [October 31, 2007, 10:17pm UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/4 "2007-10-31T22:17:28Z")

</div>

Thufir wrote:

> Why a class variable? All  
> SongList objects will use the same method, but wouldn’t they use the  
> same method even if it were an instance method? Methods are declared  
> on the class, not the instance.
> 
> Why use a class method in the first example, though?

So that you can check whether a Song is too long without having to  
create a SongList object:

#---------  
class Song  
attr\_accessor :duration

def initialize(len)  
@duration = len  
end  
end

class SongList  
MaxTime = 5\*60

def SongList.isTooLong(aSong)  
return aSong.duration \> MaxTime  
end  
end

#------------

s = Song.new(10)  
puts SongList.isTooLong(s)

Otherwise, you would have to write:

s = Song.new(10)  
sl = SongList.new()  
puts sl.isTooLong(s)

Does that make sense for this example? Who knows.

---

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [November 1, 2007, 4:20am UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/5 "2007-11-01T04:20:51Z")

</div>

On Oct 31, 5:28 pm, Thufir [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> On Oct 31, 2:17 pm, 7stud – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
> What would be a case where there’s a SongList object, though? Or, if  
> there are class methods then generally there won’t be objects of that  
> class?

class Rectangle  
def self.all  
@all ||= []  
end

```
def initialize( width, length )
  @width, @length = width, length
  self.class.all << self
end

def self.square( length )
  new( length, length
end

def self.double( width )
  new( width, width * 2 )
end

```

end

r1 = Rectangle.new( 5, 7 )  
r2 = Rectangle.square( 15 )  
r3 = Rectangle.double( 6 )  
p Rectangle.all

That’s a very simple example of two common situations for me: using  
class methods to report information about all instances of the class  
(which I’m manually tracking here), and using class methods as  
alternative constructors that return specialized instances.

---

<div class="post-metadata">

**Author:** ![Thufir](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/t/ee7513/32.png) [@Thufir](https://www.ruby-forum.com/u/Thufir)\
**Post date:** [November 1, 2007, 1:03am UTC](https://www.ruby-forum.com/t/why-or-when-to-use-a-class-method/118875/6 "2007-11-01T01:03:30Z")

</div>

Thufir wrote:

> On Oct 31, 2:17 pm, 7stud – [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
> […]
> 
> > > Why use a class method in the first example, though?
> > 
> > So that you can check whether a Song is too long without having to  
> > create a SongList object:  
> > […]
> 
> What would be a case where there’s a SongList object, though?

class Song  
attr\_accessor :duration

def initialize(len)  
@duration = len  
end  
end

class SongList  
MaxTime = 5\*60  
attr\_accessor :songs

def initialize(song\_arr)  
@songs = song\_arr  
end

def isTooLong(aSong)  
return aSong.duration \> MaxTime  
end  
end

my\_playlist = SongList.new([Song.new(10), Song.new(4)])  
song = my\_playlist.songs[0]  
puts my\_playlist.isTooLong(song)

> Or, if  
> there are class methods then generally there won’t be objects of that  
> class?

If you will never have a need to create objects of the class, then I  
think you might just create a Module. On the other hand creating a  
class where you can call class methods without objects and create  
objects and call instance methods gives you more options. More options  
allows more flexibility.
