7.4. Properties vs. functions

It's a good thing to store object data in variables on the object rather than key/value pairs in a properties mapping on the object.

In code, it's better to have set_xxx and query_xxx functions than to have the data stored using set("xxx", ...) and query("xxx", ...). Here's why:

7.4.1. Reliable masking

The default value for many properties is "@@query_prop". `query' is written to look for the lfun `query_prop' if it finds a property with a value of this form. The trouble is that if you `set' one of these properties to a normal value then that overwrites the default and `query_prop' no longer gets called when you call query("prop"). Avoiding properties and directly calling `query_prop' solves the problem. (This problem usually comes up only when defining intermediate "library" types like /std/scroll.c.)

7.4.2. Easier implmentation changes

A property that is stored on an object today may be better to compute on-the-fly. It's difficult to make that sort of change if many people are touching the property directly. One solution is to set the property to something of the form "@@query_prop", but then we run into the issues described above. Hiding how the underlying data is stored is a better solution.

7.4.3. No uncertainty about what to call

Some properties are manipulated with `query' and `set', and some with `query_temp' and `set_temp'. Using lfuns instead of properties alleviates any confusion about what to call on an object. This also helps catch misspellings of properties.

7.4.4. Data consistency (timing issues/order of initialization)

Sometimes one piece of data relies on another. For example, an object's short description could be considered an id; or an object's condition might be reflected in its long desc. In cases like this, keeping everything in sync becomes difficult if each aspect is stored as a separate piece of data. Selectively masking functions and computing some aspects can be more robust.

7.4.5. When it's good to use properties

Properties are still good for many things. They allow one object to set state on another arbitrary object without having the target object know anything about the source. For example, a room might set a temp property on any player entering it; then an NPC in the area could `query_temp' this property to react differently to players that have been in the room.