To all CLOS elders:
I am seeing a method *not* getting called because there is am :around
method of a superclass of the class in question available. That's
something I did not expect to happen... I have (really, really
simplified):
Using Cells (yeah, baby) ...
CL-USER > (in-package cells)
#<The CELLS package>
CELLS> (defmd frgo (family)
frgo-slot-1
frgo-slot-2
:md-name (gensym "FRGO-"))
#<STANDARD-CLASS FRGO>
CELLS> (defmd frgo-kid (frgo)
frgo-kid-slot-1
:md-name (gensym "FRGO-KID-"))
#<STANDARD-CLASS FRGO-KID>
CELLS> (defmd frgo-kid-kid (frgo-kid)
frgo-kid-kid-slot-1
:md-name (gensym "FRGO-KID-KID-"))
#<STANDARD-CLASS FRGO-KID-KID>
CELLS> (defmethod paint ((self family))
(format *debug-io* "~%-> Painting ~S." self))
#<STANDARD-METHOD PAINT (FAMILY)>
CELLS> (defmethod paint :around ((self frgo))
(format *debug-io* "~%-> AROUND Painting ~S." self))
#<STANDARD-METHOD PAINT :AROUND (FRGO)>
CELLS> (setq *kid-kid-1* (make-instance 'frgo-kid-kid
:md-name :frgo-kid-kid-1))
FRGO-KID-KID-1
CELLS> (describe *kid-kid-1*)
FRGO-KID-KID-1 is an instance of #<STANDARD-CLASS FRGO-KID-KID>:
The following slots have :INSTANCE allocation:
.MD-STATE :AWAKE
.AWAKEN-ON-INIT-P NIL
.CELLS ((.KIDS . <0:A .KIDS/FRGO-KID-KID-1 = NIL>))
.CELLS-FLUSHED NIL
ADOPT-CT 0
.MD-NAME :FRGO-KID-KID-1
.FM-PARENT NIL
.DBG-PAR NIL
.VALUE NIL
REGISTER? NIL
ZDBG NIL
.KID-SLOTS NIL
.KIDS NIL
REGISTRY? NIL
REGISTRY NIL
FRGO-SLOT-1 NIL
FRGO-SLOT-2 NIL
FRGO-KID-SLOT-1 NIL
FRGO-KID-KID-SLOT-1 NIL
CELLS> (paint *kid-kid-1*)
-> AROUND Painting FRGO-KID-KID-1.
NIL
CELLS>
Why is my method #'paint for the kid-kid instance not called?
Inspecting the kid-kid instance shows that the precedence list is
FRGO-KID-KID, FRGO-KID, FRGO, FAMILY, MODEL, MODEL-OBJECT, STANDARD-OBJECT, T
So I tried to get the primary method for paint on the same precedence
level / class as the :around method:
(defmethod paint ((self frgo-kid-kid))
(format *debug-io* "~%-> Painting ~S." self))
#<STANDARD-METHOD PAINT (FRGO-KID-KID)>
But:
CELLS> (paint *kid-kid-1*)
-> AROUND Painting FRGO-KID-KID-1.
NIL
CELLS>
Hmmmmmm ?!? The :around method is supposed to be executed before the
primary method, yes, but the primary method should be called after the
:around method, no?
Yes, yeah, it's late here, but I seem to be either confused or just
misinformed or going wild and crazy (I learned that I better include
that last option for you guys not having to invent "better" wording ;-)
Appreciate a hint or two ...
TIA!
Frank
On 28 maio, 20:14, Frank GOENNINGER <······@googlemail.com> wrote:
> Hmmmmmm ?!? The :around method is supposed to be executed before the
> primary method, yes, but the primary method should be called after the
> :around method, no?
In the :around method, you need to call (call-next-method) in order to
continue execution. If you want just to do something before the
primary method, use the :before qualifier instead.
the :around specializer is interesting to make some tests or to change
the value returned:
(defmethod find-element :around (elt place)
(let ((found (call-next-method)))
(unless found
(error "Not found"))
(values found t)))
Gustavo.
Frank GOENNINGER <······@googlemail.com> writes:
>
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen...
But that's what around methods do... if you want to continue down and
call the next method, you might want to insert a call to
CALL-NEXT-METHOD. You don't have this in your :around below.
Cheers,
drewc
> I have (really, really
> simplified):
>
> Using Cells (yeah, baby) ...
>
> CL-USER > (in-package cells)
> #<The CELLS package>
>
> CELLS> (defmd frgo (family)
> frgo-slot-1
> frgo-slot-2
> :md-name (gensym "FRGO-"))
> #<STANDARD-CLASS FRGO>
>
> CELLS> (defmd frgo-kid (frgo)
> frgo-kid-slot-1
> :md-name (gensym "FRGO-KID-"))
> #<STANDARD-CLASS FRGO-KID>
>
> CELLS> (defmd frgo-kid-kid (frgo-kid)
> frgo-kid-kid-slot-1
> :md-name (gensym "FRGO-KID-KID-"))
> #<STANDARD-CLASS FRGO-KID-KID>
>
> CELLS> (defmethod paint ((self family))
> (format *debug-io* "~%-> Painting ~S." self))
> #<STANDARD-METHOD PAINT (FAMILY)>
>
> CELLS> (defmethod paint :around ((self frgo))
> (format *debug-io* "~%-> AROUND Painting ~S." self))
> #<STANDARD-METHOD PAINT :AROUND (FRGO)>
>
> CELLS> (setq *kid-kid-1* (make-instance 'frgo-kid-kid
> :md-name :frgo-kid-kid-1))
> FRGO-KID-KID-1
>
> CELLS> (describe *kid-kid-1*)
> FRGO-KID-KID-1 is an instance of #<STANDARD-CLASS FRGO-KID-KID>:
> The following slots have :INSTANCE allocation:
> .MD-STATE :AWAKE
> .AWAKEN-ON-INIT-P NIL
> .CELLS ((.KIDS . <0:A .KIDS/FRGO-KID-KID-1 = NIL>))
> .CELLS-FLUSHED NIL
> ADOPT-CT 0
> .MD-NAME :FRGO-KID-KID-1
> .FM-PARENT NIL
> .DBG-PAR NIL
> .VALUE NIL
> REGISTER? NIL
> ZDBG NIL
> .KID-SLOTS NIL
> .KIDS NIL
> REGISTRY? NIL
> REGISTRY NIL
> FRGO-SLOT-1 NIL
> FRGO-SLOT-2 NIL
> FRGO-KID-SLOT-1 NIL
> FRGO-KID-KID-SLOT-1 NIL
>
> CELLS> (paint *kid-kid-1*)
>
> -> AROUND Painting FRGO-KID-KID-1.
> NIL
>
> CELLS>
>
> Why is my method #'paint for the kid-kid instance not called?
>
> Inspecting the kid-kid instance shows that the precedence list is
> FRGO-KID-KID, FRGO-KID, FRGO, FAMILY, MODEL, MODEL-OBJECT, STANDARD-OBJECT, T
>
> So I tried to get the primary method for paint on the same precedence
> level / class as the :around method:
>
> (defmethod paint ((self frgo-kid-kid))
> (format *debug-io* "~%-> Painting ~S." self))
> #<STANDARD-METHOD PAINT (FRGO-KID-KID)>
>
> But:
>
> CELLS> (paint *kid-kid-1*)
>
> -> AROUND Painting FRGO-KID-KID-1.
> NIL
> CELLS>
>
> Hmmmmmm ?!? The :around method is supposed to be executed before the
> primary method, yes, but the primary method should be called after the
> :around method, no?
>
> Yes, yeah, it's late here, but I seem to be either confused or just
> misinformed or going wild and crazy (I learned that I better include
> that last option for you guys not having to invent "better" wording ;-)
>
> Appreciate a hint or two ...
>
> TIA!
>
> Frank
Frank GOENNINGER wrote:
> To all CLOS elders:
>
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen...
Cue Naggum! Please adjust your expectations (by going back to school on
GF dispatch, committing this to static memory (in re standard method
combo)):
:around literally around anything else, but ya gots to call-next-method
to get anything else.
multiple :arounds in order of decreasing class precedence (most specific
first)
:before most specific first
primary
:after most specific last
before/after cannot alter the return value or execution of other methods
primaries can get weird and call-next-method as if they were arounds,
but unlike arounds cannot head off beofre/afters.
kt
Frank GOENNINGER wrote:
> To all CLOS elders:
>
> I am seeing a method *not* getting called because there is am :around
> method of a superclass of the class in question available. That's
> something I did not expect to happen... I have (really, really
> simplified):
>
> Using Cells (yeah, baby) ...
...that explains. :-P
Pascal
--
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
Pascal Costanza <··@p-cos.net> writes:
> Frank GOENNINGER wrote:
>> To all CLOS elders:
>>
>> I am seeing a method *not* getting called because there is am :around
>> method of a superclass of the class in question available. That's
>> something I did not expect to happen... I have (really, really
>> simplified):
>>
>> Using Cells (yeah, baby) ...
>
> ...that explains. :-P
;-) Yes, somehow it does: I expected CLOS to be as simple as Cells -
which it is not. Hehe ...
Cheers
Frank
P.S. BTW all now works as CLOS was designed. I just had - as several
pointed out - to add a (call-next-method) at the end of the :around
method.
P.P.S. Wow, I am really proud we had an on-topic thread with no language
bashing so far. Well, maybe this last remark just sets off another one...
Frank GOENNINGER wrote:
> Pascal Costanza <··@p-cos.net> writes:
>
>> Frank GOENNINGER wrote:
>>> To all CLOS elders:
>>>
>>> I am seeing a method *not* getting called because there is am :around
>>> method of a superclass of the class in question available. That's
>>> something I did not expect to happen... I have (really, really
>>> simplified):
>>>
>>> Using Cells (yeah, baby) ...
>> ...that explains. :-P
>
> ;-) Yes, somehow it does: I expected CLOS to be as simple as Cells -
> which it is not. Hehe ...
>
> Cheers
> Frank
>
> P.S. BTW all now works as CLOS was designed. I just had - as several
> pointed out - to add a (call-next-method) at the end of the :around
> method.
If you have to put it at the end, a :before method is actually simpler.
Pascal
--
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) writes:
> Frank GOENNINGER <······@googlemail.com> writes:
>
> > Hmmmmmm ?!? The :around method is supposed to be executed before the
> > primary method, yes, but the primary method should be called after the
> > :around method, no?
>
> No...then it would be a :before method. An :around method goes _around_
> the primary method (i.e., instead of...you have to use CALL-NEXT-METHOD)
Amplifying. An :AROUND method allows you to put some of your code
around the primary method, in other words both before and after it. But
without the CALL-NEXT-METHOD there wouldn't be any way for the compiler
to know what part of your around method is supposed to be done before
the primary method and what part is supposed to be after.
--
Thomas A. Russ, USC/Information Sciences Institute