ruby学习笔记系列(2)

class variables & class methods

A class variable is shared among all objects of a class, and it is also accessible to
the class methods that we’ll describe later. Only one copy of a particular class variable
exists for a given class. Class variable names start with two “at” signs, such as @@count.
Unlike global and instance variables, class variables must be initialized before they
are used. Often this initialization is just a simple assignment in the body of the class
definition.
For example, our jukebox may want to record how many times each 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 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 # same as @plays = @plays + 1
@@plays += 1
"This song: #@plays plays. Total #@@plays plays."
end
end
For debugging purposes, we’ve arranged for Song#play to return a string containing
the number of times this song has been played, along with the total number of plays for
all songs.We can test this easily.
s1 = Song.new("Song1", "Artist1", 234) # test songs..
s2 = Song.new("Song2", "Artist2", 345)
s1.play ! "This song: 1 plays. Total 1 plays."
s2.play ! "This song: 1 plays. Total 2 plays."
s1.play ! "This song: 2 plays. Total 3 plays."
s1.play ! "This song: 3 plays. Total 4 plays."
Class variables are private to a class and its instances. If you want to make them accessible
to the outside world, you’ll need to write an accessor method. This method could
be either an instance method or, leading us neatly to the next section, a class method.
Class Methods
Sometimes a class needs to provide methods that work without being tied to any particular
object. We’ve already come across one such method. The new method creates a
new Song object but is not itself associated with a particular song.
song = Song.new(....)
You’ll find class methods sprinkled throughout the Ruby libraries. For example, objects
of class File represent open files in the underlying file system. However, class File
also provides several class methods for manipulating files that aren’t open and therefore
don’t have a File object. If you want to delete a file, you call the class method
File.delete, passing in the name.
File.delete("doomed.txt")
Class methods are distinguished from instance methods by their definition; class methods
are defined by placing the class name and a period in front of the method name (but
also see the sidebar on page 34).
class Example
def instance_method # instance method
end
def Example.class_method # class method
end
end

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
MAX_TIME = 5*60 # 5 minutes
def SongList.is_too_long(song)
return song.duration > MAX_TIME
end
end
song1 = Song.new("Bicylops", "Fleck", 260)
SongList.is_too_long(song1) ! false
song2 = Song.new("The Calling", "Santana", 468)
SongList.is_too_long(song2) ! true

你可能感兴趣的:(Ruby)