summaryrefslogtreecommitdiff
path: root/doc/misc/eieio.texi
diff options
context:
space:
mode:
authorStefan Monnier <monnier@iro.umontreal.ca>2017-02-28 11:11:01 -0500
committerStefan Monnier <monnier@iro.umontreal.ca>2017-02-28 11:11:01 -0500
commit0fa594172709770a431121360f8f122df14d6259 (patch)
tree10775b677d5899dda45ee24976793973becbf889 /doc/misc/eieio.texi
parent8d7a3f489082e2aaf4ff238613a497cc03d833ae (diff)
downloademacs-0fa594172709770a431121360f8f122df14d6259.tar.gz
* doc/misc/eieio.texi: Update to account for the cl-generic facilities
(Quick Start, Class Options, Generics): Adjust names for cl-generic. (Methods): Document cl-defmethod. Explain in more detail the order in which the various methods are executed. Document the conditions under which a method is redefined. Remove reference to `eieio-generic-call-arglst`. Don't document the precise return value of cl-next-method-p. (Static Methods): Adjust to use `subclass` specializer. (Method Invocation): Use cl-call-next-method and drop mention of :primary. (Signal Handling, Signals): Adjust names and args for cl-generic; add cl-no-primary-method. (CLOS compatibility, Wish List): Adjust to new featureset.
Diffstat (limited to 'doc/misc/eieio.texi')
-rw-r--r--doc/misc/eieio.texi238
1 files changed, 121 insertions, 117 deletions
diff --git a/doc/misc/eieio.texi b/doc/misc/eieio.texi
index 3820bd50dfc..ce31bc84b4e 100644
--- a/doc/misc/eieio.texi
+++ b/doc/misc/eieio.texi
@@ -112,7 +112,7 @@ three slots named @code{name}, @code{birthday}, and @code{phone}:
Each class can have methods, which are defined like this:
@example
-(defmethod call-record ((rec record) &optional scriptname)
+(cl-defmethod call-record ((rec record) &optional scriptname)
"Dial the phone for the record REC.
Execute the program SCRIPTNAME to dial the phone."
(message "Dialing the phone for %s" (oref rec name))
@@ -170,7 +170,7 @@ or
In these examples, @eieio{} automatically examines the class of
@code{rec}, and ensures that the method defined above is called. If
@code{rec} is some other class lacking a @code{call-record} method, or
-some other data type, Emacs signals a @code{no-method-definition}
+some other data type, Emacs signals a @code{cl-no-applicable-method}
error. @ref{Signals}.
@node Introduction
@@ -589,9 +589,9 @@ This option is specific to Emacs, and is not in the CLOS spec.
@item :method-invocation-order
This controls the order in which method resolution occurs for
-@code{:primary} methods in cases of multiple inheritance. The order
+methods in cases of multiple inheritance. The order
affects which method is called first in a tree, and if
-@code{call-next-method} is used, it controls the order in which the
+@code{cl-call-next-method} is used, it controls the order in which the
stack of methods are run.
Valid values are:
@@ -817,19 +817,19 @@ provides a function binding and the base documentation for the method
symbol (@pxref{Symbol Components,,,elisp,GNU Emacs Lisp Reference
Manual}).
-@defmac defgeneric method arglist [doc-string]
+@defmac cl-defgeneric method arglist [doc-string]
This macro turns the (unquoted) symbol @var{method} into a function.
@var{arglist} is the default list of arguments to use (not implemented
yet). @var{doc-string} is the documentation used for this symbol.
A generic function acts as a placeholder for methods. There is no
-need to call @code{defgeneric} yourself, as @code{defmethod} will call
+need to call @code{cl-defgeneric} yourself, as @code{cl-defmethod} will call
it if necessary. Currently the argument list is unused.
-@code{defgeneric} signals an error if you attempt to turn an existing
+@code{cl-defgeneric} signals an error if you attempt to turn an existing
Emacs Lisp function into a generic function.
-You can also create a generic method with @code{defmethod}
+You can also create a generic method with @code{cl-defmethod}
(@pxref{Methods}). When a method is created and there is no generic
method in place with that name, then a new generic will be created,
and the new method will use it.
@@ -842,31 +842,26 @@ only occurs for the first argument, so the @var{arglist} is not used.
@node Methods
@section Methods
-A method is a function that is executed if the first argument passed
-to it matches the method's class. Different @eieio{} classes may
+A method is a function that is executed if the arguments passed
+to it matches the method's specializers. Different @eieio{} classes may
share the same method names.
-Methods are created with the @code{defmethod} macro, which is similar
+Methods are created with the @code{cl-defmethod} macro, which is similar
to @code{defun}.
-@defmac defmethod method [:before | :primary | :after | :static ] arglist [doc-string] forms
+@defmac cl-defmethod method [:before | :around | :after ] arglist [doc-string] forms
@var{method} is the name of the function to create.
-@code{:before} and @code{:after} specify execution order (i.e., when
-this form is called). If neither of these symbols are present, the
-default priority is used (before @code{:after} and after
-@code{:before}); this default priority is represented in CLOS as
-@code{:primary}.
+@code{:before}, @code{:around}, and @code{:after} specify execution order
+(i.e., when this form is called). If none of these symbols are present, the
+method is said to be a @emph{primary}.
-@b{Note:} The @code{:BEFORE}, @code{:PRIMARY}, @code{:AFTER}, and
-@code{:STATIC} method tags were in all capital letters in previous
-versions of @eieio{}.
-
-@var{arglist} is the list of arguments to this method. The first
-argument in this list---and @emph{only} the first argument---may have
-a type specifier (see the example below). If no type specifier is
-supplied, the method applies to any object.
+@var{arglist} is the list of arguments to this method. The mandatory arguments
+in this list may have a type specializer (see the example below) which means
+that the method will only apply when those arguments match the given type
+specializer. An argument with no type specializer means that the method
+applies regardless of its value.
@var{doc-string} is the documentation attached to the implementation.
All method doc-strings are incorporated into the generic method's
@@ -881,7 +876,7 @@ In the following example, we create a method @code{mymethod} for the
@code{classname} class:
@example
-(defmethod mymethod ((obj classname) secondarg)
+(cl-defmethod mymethod ((obj classname) secondarg)
"Doc string" )
@end example
@@ -889,84 +884,86 @@ In the following example, we create a method @code{mymethod} for the
This method only executes if the @var{obj} argument passed to it is an
@eieio{} object of class @code{classname}.
-A method with no type specifier is a @dfn{default method}. If a given
+A method with no type specializer is a @dfn{default method}. If a given
class has no implementation, then the default method is called when
that method is used on a given object of that class.
-Only one default method per execution specifier (@code{:before},
-@code{:primary}, or @code{:after}) is allowed. If two
-@code{defmethod}s appear with @var{arglist}s lacking a type specifier,
-and having the same execution specifier, then the first implementation
-is replaced.
+Only one method per combination of specializers and qualifiers (@code{:before},
+@code{:around}, or @code{:after}) is kept. If two @code{cl-defmethod}s appear
+with the same specializers and the same qualifiers, then the second
+implementation replaces the first.
When a method is called on an object, but there is no method specified
for that object, but there is a method specified for object's parent
-class, the parent class' method is called. If there is a method
+class, the parent class's method is called. If there is a method
defined for both, only the child's method is called. A child method
-may call a parent's method using @code{call-next-method}, described
+may call a parent's method using @code{cl-call-next-method}, described
below.
If multiple methods and default methods are defined for the same
method and class, they are executed in this order:
@enumerate
-@item method :before
-@item default :before
-@item method :primary
-@item default :primary
-@item method :after
-@item default :after
+@item :around methods
+The most specific @code{:around} method is called first, which may invoke the
+less specific ones via @code{cl-call-next-method}. If it doesn't invoke
+@code{cl-call-next-method}, then no other methods will be executed. When there
+are no more @code{:around} methods to call, falls through to run the other
+(non-@code{:around}) methods.
+@item :before methods
+Called in sequence from most specific to least specific.
+@item primary methods
+The most specific method is called, which may invoke the less specific
+ones via @code{cl-call-next-method}.
+@item :after methods
+Called in sequence from least specific to most specific.
@end enumerate
-If no methods exist, Emacs signals a @code{no-method-definition}
-error. @xref{Signals}.
+If no methods exist, Emacs signals a @code{cl-no-applicable-method} error.
+@xref{Signals}. If methods exist but none of them are primary, Emacs
+signals a @code{cl-no-primary-method} error. @xref{Signals}.
-@defun call-next-method &rest replacement-args
-@anchor{call-next-method}
+@defun cl-call-next-method &rest replacement-args
+@anchor{cl-call-next-method}
This function calls the superclass method from a subclass method.
This is the ``next method'' specified in the current method list.
-If @var{replacement-args} is non-@code{nil}, then use them instead of
-@code{eieio-generic-call-arglst}. At the top level, the generic
-argument list is passed in.
+If @var{replacement-args} is non-@code{nil}, then use them instead of the
+arguments originally provided to the method.
-Use @code{next-method-p} to find out if there is a next method to
-call.
+Can only be used from within the lexical body of a primary or around method.
@end defun
-@defun next-method-p
-@anchor{next-method-p}
+@defun cl-next-method-p
+@anchor{cl-next-method-p}
Non-@code{nil} if there is a next method.
-Returns a list of lambda expressions which is the @code{next-method}
-order.
-@end defun
-
-At present, @eieio{} does not implement all the features of CLOS:
-@enumerate
-@item
-There is currently no @code{:around} tag.
-@item
-CLOS allows multiple sets of type-cast arguments, but @eieio{} only
-allows the first argument to be cast.
-@end enumerate
+Can only be used from within the lexical body of a primary or around method.
+@end defun
@node Static Methods
@section Static Methods
Static methods do not depend on an object instance, but instead
operate on a class. You can create a static method by using
-the @code{:static} key with @code{defmethod}.
+the @code{subclass} specializer with @code{cl-defmethod}:
+
+@example
+(cl-defmethod make-instance ((class (subclass mychild)) &rest args)
+ (let ((new (cl-call-next-method)))
+ (push new all-my-children)
+ new))
+@end example
-The first argument of a @code{:static} method will be a class rather than an
+The first argument of a static method will be a class rather than an
object. Use the functions @code{oref-default} or @code{oset-default} which
will work on a class.
-A class's @code{make-instance} method is defined as a @code{:static}
+A class's @code{make-instance} method is defined as a static
method.
-@b{Note:} The @code{:static} keyword is unique to @eieio{}.
+@b{Note:} The @code{subclass} specializer is unique to @eieio{}.
@c TODO - Write some more about static methods here
@@ -977,9 +974,9 @@ When classes are defined, you can specify the
@code{:method-invocation-order}. This is a feature specific to EIEIO.
This controls the order in which method resolution occurs for
-@code{:primary} methods in cases of multiple inheritance. The order
+methods in cases of multiple inheritance. The order
affects which method is called first in a tree, and if
-@code{call-next-method} is used, it controls the order in which the
+@code{cl-call-next-method} is used, it controls the order in which the
stack of methods are run.
The original EIEIO order turned out to be broken for multiple
@@ -1297,8 +1294,7 @@ class.
@defmethod eieio-instance-tracker initialize-instance obj slot
This method is defined as an @code{:after} method.
-It adds new instances to the master list. Do not overload this method
-unless you use @code{call-next-method.}
+It adds new instances to the master list.
@end defmethod
@defmethod eieio-instance-tracker delete-instance obj
@@ -1582,7 +1578,7 @@ Additional useful methods defined on the base subclass are:
Make a copy of @var{obj}, and then apply @var{params}.
@var{params} is a parameter list of the same form as @var{initialize-instance}
which are applied to change the object. When overloading @dfn{clone}, be
-sure to call @dfn{call-next-method} first and modify the returned object.
+sure to call @dfn{cl-call-next-method} first and modify the returned object.
@end defun
@defun object-print this &rest strings
@@ -1595,7 +1591,7 @@ It is sometimes useful to put a summary of the object into the
default #<notation> string when using eieio browsing tools.
Implement this function and specify @var{strings} in a call to
-@dfn{call-next-method} to provide additional summary information.
+@dfn{cl-call-next-method} to provide additional summary information.
When passing in extra strings from child classes, always remember
to prepend a space.
@@ -1604,10 +1600,11 @@ to prepend a space.
(value)
"Object containing one data slot.")
-(defmethod object-print ((this data-object) &optional strings)
+(cl-defmethod object-print ((this data-object) &optional strings)
"Return a string with a summary of the data object as part of the name."
- (apply 'call-next-method this
- (cons (format " value: %s" (render this)) strings)))
+ (apply #'cl-call-next-method this
+ (format " value: %s" (render this))
+ strings))
@end example
Here is what some output could look like:
@@ -1667,24 +1664,36 @@ In @var{clos}, the argument list is (@var{class} @var{object} @var{slot-name}),
@var{eieio} can only dispatch on the first argument, so the first two are swapped.
@end defun
-@defun no-applicable-method object method &rest args
-@anchor{no-applicable-method}
-Called if there are no implementations for @var{object} in @var{method}.
-@var{object} is the object which has no method implementation.
-@var{args} are the arguments that were passed to @var{method}.
+@defun cl-no-applicable-method generic &rest args
+@anchor{cl-no-applicable-method}
+Called if there are no methods applicable for @var{args} in the generic
+function @var{generic}.
+@var{args} are the arguments that were passed to @var{generic}.
Implement this for a class to block this signal. The return
value becomes the return value of the original method call.
@end defun
-@defun no-next-method object &rest args
-@anchor{no-next-method}
-Called from @dfn{call-next-method} when no additional methods are available.
-@var{object} is othe object being called on @dfn{call-next-method}.
+@defun cl-no-primary-method generic &rest args
+@anchor{cl-no-primary-method}
+Called if there are methods applicable for @var{args} in the generic
+function @var{generic} but they are all qualified.
+@var{args} are the arguments that were passed to @var{generic}.
+
+Implement this for a class to block this signal. The return
+value becomes the return value of the original method call.
+@end defun
+
+@defun cl-no-next-method generic method &rest args
+@anchor{cl-no-next-method}
+Called from @dfn{cl-call-next-method} when no additional methods are available.
+@var{generic} is the generic function being called on
+@dfn{cl-call-next-method}, @var{method} is the method where
+@dfn{cl-call-next-method} was called, and
@var{args} are the arguments it is called by.
-This method signals @dfn{no-next-method} by default. Override this
+This method signals @dfn{cl-no-next-method} by default. Override this
method to not throw an error, and its return value becomes the
-return value of @dfn{call-next-method}.
+return value of @dfn{cl-call-next-method}.
@end defun
@node Signals
@@ -1699,23 +1708,29 @@ This signal is called when an attempt to reference a slot in an
it.
@end deffn
-@deffn Signal no-method-definition method arguments
-This signal is called when @var{method} is called, with @var{arguments}
-and nothing is resolved. This occurs when @var{method} has been
+@deffn Signal cl-no-applicable-method generic arguments
+This signal is called when @var{generic} is called, with @var{arguments}
+and nothing is resolved. This occurs when @var{generic} has been
defined, but the arguments make it impossible for @eieio{} to determine
which method body to run.
To prevent this signal from occurring in your class, implement the
-method @code{no-applicable-method} for your class. This method is
+method @code{cl-no-applicable-method} for your class. This method is
called when to throw this signal, so implementing this for your class
allows you block the signal, and perform some work.
@end deffn
-@deffn Signal no-next-method class arguments
-This signal is called if the function @code{call-next-method} is called
+@deffn Signal cl-no-primary-method generic arguments
+Like @code{cl-no-applicable-method} but applies when there are some applicable
+methods, but none of them are primary. You can similarly block it by
+implementing a @code{cl-no-primary-method} method.
+@end deffn
+
+@deffn Signal cl-no-next-method class arguments
+This signal is called if the function @code{cl-call-next-method} is called
and there is no next method to be called.
-Overload the method @code{no-next-method} to protect against this signal.
+Overload the method @code{cl-no-next-method} to protect against this signal.
@end deffn
@deffn Signal invalid-slot-type slot spec value
@@ -1796,22 +1811,17 @@ Make instance works as expected, however it just uses the @eieio{} instance
creator automatically generated when a new class is created.
@xref{Making New Objects}.
-@item defgeneric
-Creates the desired symbol, and accepts all of the expected arguments
-except @code{:around}.
-
-@item defmethod
-Calls defgeneric, and accepts most of the expected arguments. Only
-the first argument to the created method may have a type specifier.
-To type cast against a class, the class must exist before defmethod is
-called. In addition, the @code{:around} tag is not supported.
-
-@item call-next-method
-Inside a method, calls the next available method up the inheritance tree
-for the given object. This is different than that found in CLOS because
-in @eieio{} this function accepts replacement arguments. This permits
-subclasses to modify arguments as they are passed up the tree. If no
-arguments are given, the expected CLOS behavior is used.
+@item cl-defgeneric
+Creates the desired symbol, and accepts most of the expected arguments of
+CLOS's @code{defgeneric}.
+
+@item cl-defmethod
+Accepts most of the expected arguments of CLOS's @code{defmethod}. To type
+cast against a class, the class must exist before @code{cl-defmethod}
+is called.
+
+@item cl-call-next-method
+Works just like CLOS's @code{call-next-method}.
@end table
CLOS supports the @code{describe} command, but @eieio{} provides
@@ -1834,13 +1844,7 @@ Some important compatibility features that would be good to add are:
@enumerate
@item
-Support for metaclasses and EQL specialization.
-@item
-@code{:around} method key.
-@item
-Method dispatch for built-in types.
-@item
-Method dispatch for multiple argument typing.
+Support for metaclasses.
@item
Improve integration with the @file{cl} package.
@end enumerate