The
Song
objects we've created so far have an internal state (such as
the song title and artist). That state is private to those
objects---no other object can access an object's instance variables.
In general, this is a Good Thing. It means that the object is solely
responsible for maintaining its own consistency.
However, an object that is totally secretive is pretty useless---you
can create it, but then you can't do anything with it. You'll normally
define methods that let you access and manipulate the state of an
object, allowing the outside world to interact with the object. These
externally visible facets of an object are called its
attributes.
For our
Song
objects, the first thing we may need is the ability
to find out the title and artist (so we can display them while the
song is playing) and the duration (so we can display some kind of
progress bar).
class Song
|
def name
|
@name
|
end
|
def artist
|
@artist
|
end
|
def duration
|
@duration
|
end
|
end
|
aSong = Song.new("Bicylops", "Fleck", 260)
|
aSong.artist
|
� |
"Fleck"
|
aSong.name
|
� |
"Bicylops"
|
aSong.duration
|
� |
260
|
Here we've defined three accessor methods to return the values of the
three instance attributes. Because this is such a common idiom, Ruby
provides a convenient shortcut:
attr_reader
creates these
accessor methods for you.
class Song
|
attr_reader :name, :artist, :duration
|
end
|
aSong = Song.new("Bicylops", "Fleck", 260)
|
aSong.artist
|
� |
"Fleck"
|
aSong.name
|
� |
"Bicylops"
|
aSong.duration
|
� |
260
|
This example has introduced something new. The construct
:artist
is an expression that returns a
Symbol
object corresponding to
artist
. You can think of
:artist
as meaning the
name
of the variable
artist
, while plain
artist
is the
value of the variable. In this example, we named the accessor
methods
name
,
artist
, and
duration
. The
corresponding instance variables,
@name
,
@artist
, and
@duration
, will be created automatically. These accessor methods
are identical to the ones we wrote by hand earlier.