When a message is sent to an object the object system will use the object and the method selector to find the appropriate piece of code to execute. Different objects may thus respond differently to the same message. A linear regression model and a nonlinear regression model might both respond to a :coef-estimates message but they will execute different code to compute their responses.
The code used by an object to respond to a message is called a method. Objects are organized in a hierarchy in which objects inherit from other objects. If an object does not have a method of its own for responding to a message it will use a method inherited from one of its ancestors. The send function will move up the precedence list of an object's ancestors until a method for a message is found.
Most of the objects encountered so far inherit directly from prototype objects. Scatterplots inherit from scatterplot-proto, histograms from histogram-proto, regression models from regression-model-proto. Prototypes are just like any other objects. They are essentially typical versions of a certain kind of object that define default behavior. Almost all methods are owned by prototypes. But any object can own a method, and in the process of debugging a new method it is often better to attach the method to a separate object constructed for that purpose instead of the prototype.
To add a method to an object you can use the defmeth macro. As an example, in Section 7 we calculated Cook's distances for a regression model. If you find that you are doing this very frequently then you might want to define a :cooks-distances method. The general form of a method definition is:
(defmeth object :new-method arg-list body)object is the object that is to own the new method. In the case of regression models this can be either a specific regression model or the prototype that all regression models inherit from, regression-model-proto. The argument :new-method is the message selector for your method; in our case this would be :cooks-distances. The argument arg-list is the list of argument names for your method, and body is one or more expressions making up the body of the method. When the method is used each of these expressions will be evaluated, in the order in which they appear.
Here is an expression that will install the :cooks-distances method:
(defmeth regression-model-proto :cooks-distances () "Message args: () Returns Cooks distances for the model." (let* ((leverages (send self :leverages)) (studres (/ (send self :residuals) (* (send self :sigma-hat) (sqrt (- 1 leverages))))) (num-coefs (send self :num-coefs))) (* (^ studres 2) (/ leverages (- 1 leverages) num-coefs)))))The variable self refers to the object that is receiving the message. This definition is close to the definition of this method supplied in the file regression.lsp.