[closer-devel] interesting contextl use-case
Pascal Costanza
pc at p-cos.net
Tue Jun 12 18:02:38 UTC 2007
On 12 Jun 2007, at 11:36, Attila Lendvai wrote:
> hi!
>
> we would like to add new slots to a class when being inside a layer.
> the need comes when running some algorithm to calculate some new
> properties of some instances. the usual solution is to set up a
> hashtable, and add the extra property value in that hashtable.
>
> what we would like to do is to define new slots for a class but only
> in a given layer. so make-instance'ing that class when the layer is
> active should return instances with the extra slots.
>
> i'm not sure if this is already possible, but a possible
> implementation would be to delegate make-instance to
> make-layered-instance or make-instance-using-layer, then consult the
> layer context and as needed return an unnamed subclass of the actual
> class that contains the extra slots.
>
> thoughts?
I don't fully understand what you are asking for, but let me make
some guesses. ;)
The basic functionality, as far as I see it, is already available:
You can give partial definitions for the same layered class
associated with different layers. This effectively allows you to
define slots that are only visible when some layer is active. The
basic approach looks like this:
(define-layered-class my-object ()
((foo :initarg :foo :layered-accessor foo)))
(deflayer l1)
(define-layered-class my-object :in-layer l1 ()
((bar :initarg :bar :layered-accessor bar)))
The effect of this definition is as follows:
- The slot foo is always visible.
- The slot bar can only be accessed via the accessor methods bar and
(setf bar) when the layer l1 is active.
- If you don't initialize a slot with a keyword argument (:foo
or :bar) it will remain unbound (unless it has an :initform).
In ContextL, the various slots from partial class definitions that
contribute to a layered class are always allocated in instances of
that class. However, as in CLOS, you always have control over whether
they are actually bound or not. I have thought about making
allocation of such slots variable, but I have decided against because
(a) I don't expect the memory overhead to be substantial enough to
warrant a more complex solution and (b) it's always easy to add
optional slots with another metaclass that uses hashtables in the
background (one of the standard CLOS MOP examples). It should be
relatively straightforward to add this to ContextL at the user level.
BTW, the restriction of access to slots coming from specific layers
is only in effect for accessor (reader and writer) methods. slot-
value and (setf slot-value) can always access slots, no matter what
layer is active, because they are the low-level access mechanisms
that are important for, for example, debuggers, inspectors, etc.
If you indeed want to ensure that, based on the set of currently
active layers, instances of a different class are created such that
the slots from other non-active layers are definitely not present,
then you can achieve this by implementing your own abstraction on top
of CLOS / ContextL. Just implement your own layered function for
creating instances, say create-instance, then you can define layered
methods on it that change what kind of instance is actually created.
It could have been possible to add such functionality to make-
instance from within ContextL - however, modifying make-instance that
way is probably not a good idea because CLOS implementations
typically try to optimize instance creation as heavily as possible.
Whenever you define methods on make-instance, there is a chance that
you slow down the overall CLOS runtime. (That's just a guess, though,
I could be wrong here.)
I have probably not quite got the gist of what you actually want, but
it's now your turn to clarify my misunderstandings. ;-)
Cheers,
Pascal
--
Pascal Costanza, mailto:pc at p-cos.net, http://p-cos.net
Vrije Universiteit Brussel, Programming Technology Lab
Pleinlaan 2, B-1050 Brussel, Belgium
More information about the closer-devel
mailing list