drkm writes:
> I found that the value of a generic function call is not correct.
> When :AFTER methods exist, the value of the last called become the
> value of the generic call. But the value of the generic call must be
> always the value of the primary method called. Example:
> (defclass A () ())
> (defmethod F ((a A))
> (message "primary"))
> (defmethod F :AFTER ((a A))
> (message ":after"))
> (F (A nil))
> ==> ":after"
I just checked the CLOS specs (X3J13 Document 88-022R June 1988), it
says, page 1-30:
- All the :before methods are called, in most-specific-first
order. Their values are ignored. An error is signaled if
call-next-method is used in a :before method.
- The most specific primary method is called. Inside the body of
a primary method, call-next-method may be used [...].
- All the :after methods are called in most-specific-last order.
Their values are ignored. An error is signaled if
call-next-method is used in an :after method.
So, clearly, the example above must returns "primary". Maybe the
following patch to eieio-tests.el may be added.
Thanks,
--drkm
*** eieio-tests.el-orig Fri Jul 30 19:59:54 2004
--- eieio-tests.el Fri Mar 11 18:17:29 2005
***************
*** 349,354 ****
--- 349,382 ----
(error "%S" er)))))
+ ;;; Test value of a generic function call
+ ;;
+ (defvar class-fun-value-seq '())
+
+ (defmethod class-fun-value :BEFORE ((a class-a))
+ "Return `before', and push `before' in `class-fun-value-seq'."
+ (push 'before class-fun-value-seq)
+ 'before)
+
+ (defmethod class-fun-value :PRIMARY ((a class-a))
+ "Return `primary', and push `primary' in `class-fun-value-seq'."
+ (push 'primary class-fun-value-seq)
+ 'primary)
+
+ (defmethod class-fun-value :AFTER ((a class-a))
+ "Return `after', and push `after' in `class-fun-value-seq'."
+ (push 'after class-fun-value-seq)
+ 'after)
+
+ (let ((value (class-fun-value a)))
+ (unless (eq value 'primary)
+ (error
+ "Value of the generic function call isn't the primary method value [%S]."
+ value))
+ (unless (equal class-fun-value-seq '(after primary before))
+ (error "Methods were not called from :BEFORE to :AFTER.")))
+
+
;;; Test initialization methods
;;
(defmethod initialize-instance ((a class-a) &rest slots)
|