10.2.2 Setter methods
In most cases, the getter and setter methods that Dylan defines for each slot are perfectly adequate. In certain cases, however, you might want to change the way a getter or setter works.
For example, we can define a setter method to solve a problem in our time library. The class <time-of-day> inherits the total-seconds slot from the class <sixty-unit>. The type of the slot is <integer>. However, the semantics of <time-of-day> state that the total-seconds should not be less than 0. We can define a setter method for <time-of-day> to ensure that the new value for the total-seconds slot is 0 or greater.
In our setter method, we will use the type defined in Section 9.2, page 110, and repeated here:
// Define nonnegative integers as integers that are >= zero define constant <nonnegative-integer> = limited(<integer>, min: 0);
The setter method is as follows:
define method total-seconds-setter
(total-seconds :: <integer>, time :: <time-of-day>)
=> (total-seconds :: <nonnegative-integer>)
if (total-seconds >= 0)
next-method();
else
error("%d is invalid. total-seconds cannot be negative.", total-seconds);
end if;
end method total-seconds-setter;
When the setter for the total-seconds slot is called with an instance of <time-of-day>, the preceding method will be invoked, because it is more specific than the method that Dylan generated on the <sixty-unit> class. If the new value for the total-seconds slot is valid (that is, is greater than or equal to 0), then this method calls next-method, which invokes the setter method on <sixty-unit>. If the new value is less than 0, an error is signaled.
The following example show what happens when you call total-seconds-setter with a negative value for total-seconds:
? begin
let test-time-of-day = make(<time-of-day>);
test-time-of-day.total-seconds := -15;
end;
ERROR: -15 is invalid. total-seconds cannot be negative.
This setter method ensures that no one can assign an invalid value to the slot. For completeness, we must also ensure that no one can initialize the slot to an invalid value. The way to do that is to define an initialize method, as shown in Section 10.3.




