Sometimes you need to be able to set an attribute from outside the
object. For example, let's assume that the duration that is initially
associated with a song is an estimate (perhaps gathered from
information on a CD or in the MP3 data). The first time we play the
song, we get to find out how long it actually is, and we store this
new value back in the
Song
object.
In languages such as C++ and Java, you'd do this with
setter
functions.
class JavaSong { // Java code
private Duration myDuration;
public void setDuration(Duration newDuration) {
myDuration = newDuration;
}
}
s = new Song(....)
s.setDuration(length)
|
In Ruby, the attributes of an object can be accessed as if they were
any other variable. We've seen this above with phrases such as
aSong.name
. So, it seems natural to be able to assign to these
variables when you want to set the value of an attribute. In keeping
with the Principle of Least Surprise, that's just what you do in Ruby.
class Song
|
def duration=(newDuration)
|
@duration = newDuration
|
end
|
end
|
aSong = Song.new("Bicylops", "Fleck", 260)
|
aSong.duration
|
� |
260
|
aSong.duration = 257 # set attribute with updated value
|
aSong.duration
|
� |
257
|
The assignment ``
aSong.duration = 257
'' invokes the method
duration=
in the
aSong
object, passing it
257
as
an argument. In fact, defining a method name ending in an equals sign
makes that name eligible to appear on the left-hand side of an
assignment.
Again, Ruby provides a shortcut for creating these simple attribute
setting methods.
class Song
attr_writer :duration
end
aSong = Song.new("Bicylops", "Fleck", 260)
aSong.duration = 257
|