User Resources
› What is Dylan? › Learning Dylan › Downloads › Documentation › Wiki › Community › Dylan Competes › Supported Platforms › Screenshots › Current Limitations › Our Goals
Developer Resources
› Repository Access › Browse Repository › Bug Tracker › CVSZilla Search › Buildbot › Current Projects › Dev Tools › Submit News

[ All Fragments ]

Getters and Setters are Functions

Many object-oriented languages encourage you to define a get_foo and set_foo function for each member variable foo. These allow you to control access to the variables and provide for future extensibility. For example, set_foo could be modified to keep a table of values of foo.

Dylan provides for this extensibility without having to write the accessor functions up front. Consider a simple Dylan class:

define class <vehicle> (<object>)
  slot driver,
    required-init-keyword: driver:;
end class;

This creates two functions, driver and driver-setter. Under normal circumstances, these two functions will be inlined and optimized into direct accesses.

Dylan provides some handy syntatic sugar to make these functions look like members of a C structure:

define variable *test-car* = make(<vehicle>, driver: "Frank");

// These two expressions return the same value.
*test-car*.driver;
driver(*test-car*);

// These three statements perform the same assignment.
*test-car*.driver := "Sally";
driver(*test-car*) := "Sally";
driver-setter("Sally", *test-car*);

If you later discover that you can't allow direct access to the driver slot, you can rename the slot and create two explicit functions named driver and driver-setter to replace it. The following example maintains a hash table mapping drivers to their cars:

define constant *driver-to-car-map* = make(<table>);

define class <vehicle> (<object>)
  slot %driver,
    required-init-keyword: driver:;
end class;

define method initialize(vehicle :: <vehicle>, #key, #all-keys)
  *driver-to-car-map*[vehicle.%driver] := vehicle;
end method;

define constant driver = %driver;

define method driver-setter(driver, vehicle :: <driver>)
 => (value :: <object>)
  *driver-to-car-map*[driver] := vehicle;
  vehicle.%driver := driver;
end method;