From: Vassili Bykov
Subject: Re: Direct accessing of shared slots revisited (for CLISP)
Date:
Message-ID: <uium2r8ri.fsf@objectpeople.com>
Pierre Mai <····@cs.tu-berlin.de> wrote:
> The 'problem' of accessing shared slots of classes without going
> through a dummy instance has been raised on this newsgroup a couple
> of times, and solutions have been given for CLOS implementations
> which implement enough parts of the MOP, like the one below:
>
> (defun class-slot-value (classname name)
> [...]
>
> But it seems CLISP doesn't implement this part of the MOP, and now I'm
> looking for a somewhat elegant/efficient solution for CLISP...
Here is the idea that is suggested by the CLISP CLOS implementation --
see clos.lsp, around lines 230 (untested):
(in-package :clos)
(defun class-slot-value (class-name slot-name)
(let* ((class (find-class class-name))
(slot-location (gethash slot-name
(class-slot-location-table class)))
(value (cond ((consp slot-location)
(svref (class-shared-slots (car slot-location))
(cdr slot-location)))
(t
(slot-missing class nil slot-name 'slot-value)))))
(if (eq value unbound)
(slot-unbound class nil slot-name)
value)))
The suspicious thing is that the NIL in the calls to SLOT-MISSING and
SLOT-UNBOUND is supposed to be the instance for which the operation
failed; I am not sure passing a NIL is really a Good Thing to do.
--Vassili
Vassili Bykov <·······@objectpeople.com> writes:
> Here is the idea that is suggested by the CLISP CLOS implementation --
> see clos.lsp, around lines 230 (untested):
>
> [suggested solution snipped]
Thanks to the proposed solution, I was able to get something up and
working: The handling of #<UNBOUND> in CLISP (esp. in the interpreter)
is somewhat difficult, since this is not a real lisp value, e.g. you
cannot really bind a variable to this value. So the code in clos.lsp
used a hack (which I still don't fully understand, to be honest) to
get clos::unbound to get the required value.
With some modification the following code now seems to work in CLISP,
_BUT ONLY IF YOU COMPILE IT_. In the interpreter, CLISP interprets
the #<UNBOUND> to which value gets bound, as if value itself was
unbound, so you'd need the handler-case which I commented out in the
following code (whether this is really a good idea, and doesn't clash
with CLISP's internals I don't know, so beware):
(in-package :clos)
(let ((unbound (sys::%record-ref
(allocate-std-instance <standard-object> 2) 1)))
(defun class-slot-value (class-name slot-name)
(let* ((class (find-class class-name))
(slot-location (gethash slot-name
(class-slot-location-table class)))
(value (cond ((consp slot-location)
(svref (class-shared-slots (car slot-location))
(cdr slot-location)))
(t
(slot-missing class nil slot-name 'slot-value)))))
;; (handler-case
(if (eq value unbound)
(slot-unbound class nil slot-name)
value)
;; (unbound-variable () (slot-unbound class nil slot-name)))))
)))
> The suspicious thing is that the NIL in the calls to SLOT-MISSING and
> SLOT-UNBOUND is supposed to be the instance for which the operation
> failed; I am not sure passing a NIL is really a Good Thing to do.
It doesn't seem to cause any problems, but there might be hidden
problems, I'm not aware of...
> --Vassili
Thanks again for pointing me in the right direction...
Regs, Pierre.
--
Pierre Mai <····@cs.tu-berlin.de> http://home.pages.de/~trillian/
"Such is life." -- Fiona in "Four Weddings and a Funeral" (UK/1994)
From: Bruno Haible
Subject: Re: Direct accessing of shared slots revisited (for CLISP)
Date:
Message-ID: <6mmo12$30k@news.u-bordeaux.fr>
Pierre Mai <····@cs.tu-berlin.de> wrote:
>
> With some modification the following code now seems to work in CLISP,
> _BUT ONLY IF YOU COMPILE IT_.
You can force the entire (let ((unbound ...)) (defun ...)) to be compiled
by wrapping it in (locally (declare (compile)) ...).
A nice hack :-)
Bruno
······@clisp.cons.org (Bruno Haible) writes:
> You can force the entire (let ((unbound ...)) (defun ...)) to be compiled
> by wrapping it in (locally (declare (compile)) ...).
>
> A nice hack :-)
Thanks, it all works nicely now...
Regs, Pierre.
Below the complete version, for the archives:
(in-package :clos)
(locally (declare (compile))
(let ((unbound (sys::%record-ref
(allocate-std-instance <standard-object> 2) 1)))
(defun class-slot-value (class-name slot-name)
(let* ((class (find-class class-name))
(slot-location (gethash slot-name
(class-slot-location-table class)))
(value (cond ((consp slot-location)
(svref (class-shared-slots (car slot-location))
(cdr slot-location)))
(t
(slot-missing class nil slot-name 'slot-value)))))
(if (eq value unbound)
(slot-unbound class nil slot-name)
value)))))
--
Pierre Mai <····@cs.tu-berlin.de> http://home.pages.de/~trillian/
"Such is life." -- Fiona in "Four Weddings and a Funeral" (UK/1994)