I'm using ACL 8.0. Suppose I have:
(defclass x () ())
(defmethod foo ((self x)) 'xxxxx)
(defmethod foo ((self (eql 'x))) 'blah)
This works:
(compute-applicable-methods-using-classes (symbol-function 'foo) (list
(find-class 'x)))
(#<STANDARD-METHOD FOO (X)>)
T
This works as well:
(compute-applicable-methods-using-classes (symbol-function 'foo) '(x))
(#<STANDARD-METHOD FOO (X)>)
T
How do I apply the same technique to retrieving the eql specializer
method? I'm able to do
(compute-applicable-methods (symbol-function 'foo) '(x))
(#<STANDARD-METHOD FOO ((EQL X))>)
How can I use compute-applicable-methods-with-classes to retrieve the
eql method?
Thanks, Joel
"Joel Reymont" <······@gmail.com> writes:
> How can I use compute-applicable-methods-with-classes to retrieve the
> eql method?
I can't speak for your implementation, but my understanding of the MOP
as described by the Art of the Metaobject Protocol is that you can't.
COMPUTE-APPLICABLE-METHODS-USING-CLASSES is required to know whether
the applicable methods can be completely determined given the classes
of the arguments, and if not, to return a failure value. The reason
for this is to allow memoisation of this (expensive) process: see the
descriptions of COMPUTE-APPLICABLE-METHODS,
COMPUTE-APPLICABLE-METHODS-USING-CLASSES and
COMPUTE-DISCRIMINATING-FUNCTION in the MOP dictionary (available
online as well as in the AMOP book).
Christophe
Joel Reymont wrote:
> I'm using ACL 8.0. Suppose I have:
>
> (defclass x () ())
> (defmethod foo ((self x)) 'xxxxx)
> (defmethod foo ((self (eql 'x))) 'blah)
>
> This works:
>
> (compute-applicable-methods-using-classes (symbol-function 'foo) (list
> (find-class 'x)))
> (#<STANDARD-METHOD FOO (X)>)
> T
This is correct.
> This works as well:
>
> (compute-applicable-methods-using-classes (symbol-function 'foo) '(x))
> (#<STANDARD-METHOD FOO (X)>)
> T
This is not covered by the CLOS MOP specification.
> How do I apply the same technique to retrieving the eql specializer
> method? I'm able to do
>
> (compute-applicable-methods (symbol-function 'foo) '(x))
> (#<STANDARD-METHOD FOO ((EQL X))>)
>
> How can I use compute-applicable-methods-with-classes to retrieve the
> eql method?
You can't use compute-applicable-methods-using-classes here because it
is specified to only work on methods with class specializers.
If you only need this for inspection purposes, you can safely use just
compute-applicable-methods, because it will also return methods that are
specialized on classes if any. There is nothing you can miss by not
using compute-applicable-methods-using-classes here.
The latter exists purely for optimization purposes. If you need it, the
idiom to use it would be this:
(multiple-value-bind
(methods acceptablep)
(compute-applicable-methods-using-classes ...)
(if acceptablep
methods
(compute-applicable-methods ...)))
If compute-applicable-methods-using-classes returns a second value of
true, you can also cache the applicable methods. However, in order to
get really efficient code, you probably have to invest a lot more work.
This was one part of the metaobject protocol that they couldn't figure
out how to make it work well in all desirable respects.
Pascal
--
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/