Next: , Previous: defobject, Up: Objects Dictionary


defproto
— Macro: defproto proto-name {parent-objects} ({property-spec}*) option-spec*

=> new-object

     proto-name ::= symbol
     parent-objects ::= {object | (object*)}
     property-spec ::= (property-name property-value property-option*)
     property-name ::= symbol
     property-value ::= object
     property-option ::= {:reader {reader-message-name | nil}}* |
                         {:writer {writer-message-name | nil}}* |
                         {:accessor {reader-message-name | t | nil}}*
     message-name ::= {symbol | (quote (setf symbol))}
     option-spec ::= :nickname lisp-object |
                     :documentation docstring

Arguments and Values:

proto-name — a non-keyword symbol.

parent-object — an object, to be added as a parent.

property-name — a symbol, not evaluated.

property-value — a form, evaluated to produce an initial value for the corresponding property property-name.

reader/writer/accessor — can be supplied more than once for each property. If NIL is given for any of these, signals an error if there is another matching definition. :accessor creates both a reader and a writer with format (accessor-name object) (setf (accessor-name object) new-value). Providing T as the argument to :accessor automatically creates an accessor for that property using the given property name.

nickname — a form, evaluated to produce the nickname for new-object, preferably a symbol.

documentation — a string of documentation for the new object.

new-object — an object, constructed according to the arguments.

Description:

DEFPROTO creates a new object with all the parent-objects as parents, and creates a dynamic binding for the symbol proto-name to the object.

After the object has been initialized, direct-properties, readers, writers, and accessors are added to the new object based on each property-spec. Unlike DEFOBJECT, DEFPROTO automatically defines accessors for each property-spec using its property-name. This behavior can be overridden by passing a :reader, :writer, and/or :accessor option.

Unless given a :nickname option, DEFPROTO uses proto-name as the new object's nickname.

If a DEFPROTO form is evaluated when the proto-name already points to an existing sheep, REINIT-OBJECT is called on the existing object to clear out the current parents and properties and set them according to the parent-objects and property-specs in the call to DEFPROTO.

Examples:

     (defproto =test-proto= () ()) => #<Object =TEST-PROTO= #x300041602BFD>
     (defproto =test-proto= () ((var "value"))) => #<Object =TEST-PROTO=#x300041602BFD>
     ;; Identity is maintained, but =test-proto= now has a new property. Removing it
     ;; in the form will remove it from the object:
     (defproto =test-proto= () ()) => #<Object =TEST-PROTO= #x300041602BFD>
     (available-properties *) => (NICKNAME)

Notes:

It is customary to name prototype objects with an equals-sign (=) at the beginning and end of the name. For example, =foo= is a good name for a prototype. This naming convention is observed for all included objects in the Sheeple library; however, programs are not required to adhere to it.