Given a slot name, is there a means of finding which classes derived from a
common root implement that slot? Suppose I have this hierarchy:
(defclass message ()
())
(defclass 014d (message)
((baud-rate)))
(defclass 016b (message)
((subrack-id)
(cardslot-id)
(channel-to-monitor)))
(defclass 0304 (message)
((subrack-id)
(cardslot-id)))
If I wanted to find out which derivatives of message contain a slot named
"subrack-id", what would be the best way of going about it?
Thanks,
Jon.
From: Nils Goesche
Subject: Re: Finding which classes implement a slot
Date:
Message-ID: <lyn0lliftt.fsf@cartan.de>
"Jon Bills" <·········@hotmail.com> writes:
> Given a slot name, is there a means of finding which classes derived
> from a common root implement that slot? Suppose I have this
> hierarchy:
>
> (defclass message ()
> ())
>
> (defclass 014d (message)
> ((baud-rate)))
>
> (defclass 016b (message)
> ((subrack-id)
> (cardslot-id)
> (channel-to-monitor)))
>
> (defclass 0304 (message)
A class name should be a non-nil symbol, not a number.
> ((subrack-id)
> (cardslot-id)))
>
> If I wanted to find out which derivatives of message contain a slot
> named "subrack-id", what would be the best way of going about it?
That's what the MetaObject Protocol (MOP) is for. In LispWorks, its
functions are exported from the HCL package. Then you can do
something like
(defpackage "SLOTS"
(:use "CL")
(:export "FIND-SLOTS"))
(in-package "SLOTS")
(defclass message ()
())
(defclass class-014d (message)
((baud-rate)))
(defclass class-016b (message)
((subrack-id)
(cardslot-id)
(channel-to-monitor)))
(defclass class-0304 (message)
((subrack-id)
(cardslot-id)))
(defun find-slots (name base)
(let (classes)
(labels ((process-class (base)
(when (find name (hcl:class-slots base)
:key #'hcl:slot-definition-name :test #'eq)
(push (class-name base) classes))
(mapc #'process-class (hcl:class-direct-subclasses base))))
(process-class (find-class base))
classes)))
and then:
SLOTS 26 > (find-slots 'subrack-id 'message)
(CLASS-016B CLASS-0304)
To find the MOP functions in other implementations (if present), look
for them with APROPOS.
Regards,
--
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x0655CFA0
Nils Goesche wrote:
> "Jon Bills" <·········@hotmail.com> writes:
>
> A class name should be a non-nil symbol, not a number.
OK, thanks for pointing that out.
>> If I wanted to find out which derivatives of message contain a slot
>> named "subrack-id", what would be the best way of going about it?
>
> That's what the MetaObject Protocol (MOP) is for.
I suspected so, but I haven't had much to do with MOP so far. AMOP is next
on my "to buy" list.
> In LispWorks, its
> functions are exported from the HCL package. Then you can do
> something like
[...]
Thanks Nils, that's exactly what I was looking for.
Jon.
On Tue, Jan 28, 2003 at 01:56:32PM -0000, Jon Bills wrote:
> Nils Goesche wrote:
> > "Jon Bills" <·········@hotmail.com> writes:
> >
> > A class name should be a non-nil symbol, not a number.
>
> OK, thanks for pointing that out.
This, BTW, doesn't stop you from using |123|, which is the symbol with
the name "123".
--
; Matthew Danish <·······@andrew.cmu.edu>
; OpenPGP public key: C24B6010 on keyring.debian.org
; Signed or encrypted mail welcome.
; "There is no dark side of the moon really; matter of fact, it's all dark."
From: Nils Goesche
Subject: Re: Finding which classes implement a slot
Date:
Message-ID: <lyisw9ifcl.fsf@cartan.de>
I <······@cartan.de> wrote:
> (defun find-slots (name base)
> (let (classes)
> (labels ((process-class (base)
> (when (find name (hcl:class-slots base)
> :key #'hcl:slot-definition-name :test #'eq)
> (push (class-name base) classes))
> (mapc #'process-class (hcl:class-direct-subclasses base))))
> (process-class (find-class base))
> classes)))
I should mention that this might return classes several times (but
should terminate in any case). If this bothers you, make that
(defun find-slots (name base)
(let (classes)
(labels ((process-class (base)
(when (find name (hcl:class-slots base)
:key #'hcl:slot-definition-name :test #'eq)
(push (class-name base) classes))
(mapc #'process-class (hcl:class-direct-subclasses base))))
(process-class (find-class base))
(delete-duplicates classes :test #'eq)))
Regards,
--
Nils G�sche
"Don't ask for whom the <CTRL-G> tolls."
PGP key ID 0x0655CFA0
From: Steven M. Haflich
Subject: Re: Finding which classes implement a slot
Date:
Message-ID: <3E376FC1.2030803@alum.mit.edu>
Nils Goesche wrote:
> (defun find-slots (name base)
> (let (classes)
> (labels ((process-class (base)
> (when (find name (hcl:class-slots base)
> :key #'hcl:slot-definition-name :test #'eq)
> (push (class-name base) classes))
> (mapc #'process-class (hcl:class-direct-subclasses base))))
> (process-class (find-class base))
> classes)))
There are a couple problems with this solution, although the general
notion is correct and pedagogiclly useful.
First, class-slots is _required_ to signal error if the class is not
yet finalized. Perhaps LispWorks is eager about finalization, but
still, it is possible to define a class that cannot be finalized, so I
can't imagine how this code could work if it encountered such a
"abstract" mixin. It would be safer to use class-direct-slots instead.
Even if modified to handle unfinalized classes, the code will still blow
up if it encounters a forward-reference-class (i.e. a not-yet-defined
subclass) because neither class-direct-slots nor class-direct-subclasses
is defined for a forward-reference-class. A fix would be to wrap a test
around the body of process-class.
Finally, this function doesn't return _classes_ that directly define a
particular slot. Rather it returns the _names_ of these classes.
Generally in MOP programming, one immediately resolves class names to
class objects, and rarely ever perform the inverse operation. The MOP
nearly everywhere operates on classes, not class names, and MOP-using
programs should do the same. Classes are first class objects with
object identity, and there are any number of circumstances where classes
might have no meaningful name, or where multiple class objects could
have the same name.
"Steven M. Haflich" <·················@alum.mit.edu> writes:
> neither class-direct-slots nor class-direct-subclasses is defined
> for a forward-reference-class.
FWIW, AMOP defines both for forward-referenced classes.