]> git.eshelyaron.com Git - emacs.git/commitdiff
* doc/misc/eieio.texi: Update to account for the cl-generic facilities
authorStefan Monnier <monnier@iro.umontreal.ca>
Tue, 28 Feb 2017 16:11:01 +0000 (11:11 -0500)
committerStefan Monnier <monnier@iro.umontreal.ca>
Tue, 28 Feb 2017 16:11:01 +0000 (11:11 -0500)
(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.

doc/misc/eieio.texi

index 3820bd50dfc16ce60d2a204164d027e7d27ce960..ce31bc84b4eab2f69a59530f496d0c22f70b3fe4 100644 (file)
@@ -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