[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

why, or when to, use a class method?

Thufir Hawat

10/31/2007 8:28:00 PM

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/Programmin...

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


5 Answers

David A. Black

10/31/2007 8:41:00 PM

0

7stud --

10/31/2007 9:17:00 PM

0

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.

--
Posted via http://www.ruby-....

Thufir Hawat

10/31/2007 11:28:00 PM

0

On Oct 31, 2:17 pm, 7stud -- <bbxx789_0...@yahoo.com> 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


7stud --

11/1/2007 12:03:00 AM

0

Thufir wrote:
> On Oct 31, 2:17 pm, 7stud -- <bbxx789_0...@yahoo.com> 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.
--
Posted via http://www.ruby-....

Phrogz

11/1/2007 3:20:00 AM

0

On Oct 31, 5:28 pm, Thufir <hawat.thu...@gmail.com> wrote:
> On Oct 31, 2:17 pm, 7stud -- <bbxx789_0...@yahoo.com> 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.