Hi,
while working with a class hierarchy similar to this
a
/ \
b c
\ /
d
I discovered surprising (to me) behavior. Each class has an
initialize-instance method and they run in one of the expected orders:
d, b, c, a.
The surprising part: each initialize-instance method uses
call-next-method. The methods of d and b provide replacement arguments
and extent the list of initargs with :c 'c and :d 'd respectively.
However, when c uses (call-next-method) the eieio-generic-call-arglst of
the original call (to initialize-instance of d) is used. I expected the
replacement arguments provided in the initialize-instance methods of d
and b to be propagated to the call of c's initialize-instance.
With instrumented methods that print their arguments, the following
happens:
(d "" :a 'a)
| d (:a a)
| b (:a a :d d)
| c (:a a :d d :b b)
| a (:a a) ; (call-next-method) in c calls a's
; initialize-instance with original argument list
I expected the result to be more like this:
(d "" :a 'a)
| d (:a a)
| b (:a a :d d)
| c (:a a :d d :b b)
| a (:a a :d d :b b) ; initialize-instance of a is called with modified
; argument list
I produced the second trace by changing the following in eieio.el
(call-next-method):
@@ -2174,6 +2222,8 @@
(apply 'no-next-method (car newargs) (cdr newargs))
(let* ((eieio-generic-call-next-method-list
(cdr eieio-generic-call-next-method-list))
+ (eieio-generic-call-arglst
+ newargs)
(scoped-class (cdr next))
(fcn (car next))
)
Is this an improvement?
Kind regards,
Jan
|