Dear All,
I am new to CLOS and am having the following problem.
I want to have a class and a subclass with the same slots, bar one or two, which
should have the same values for all instances of the class, but these values
should be different for the class and the sub-class.
I tried the following
(defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
(:default-initarg :s-1 5))
(defclass c-2 (c-1)
(:default-initarg :s-1 4))
However, when I came to create instances of the classes I found the following
behaviour.
(setq i-1 (make-instance 'c-2))
(s-1 i-1)
4
(setq i-2 (make-instance 'c-1))
(s-1 i-2)
5
(s-1 i-1)
5
Which is not what I wanted at all. (I wanted (s-1 i-1) to return 4)
What should I do to create the desired behaviour ?
Thanks for any help, Matthew.
Matthew Realff writes:
I tried the following
(defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
(:default-initarg :s-1 5))
(defclass c-2 (c-1)
(:default-initarg :s-1 4))
I think you are missing two pairs of parentheses here:
(defclass c-1 ()
((s-1 :allocation :class :accessor s-1 :initarg :s-1))
(:default-initarg :s-1 5))
(defclass c-2 (c-1)
()
(:default-initarg :s-1 4))
The inheritance semantics of the :ALLOCATION :CLASS option are
different from what you think -- the slot S-1 will get an allocation
attribute of "class C-1" and this will not change when the slot is
inherited by C-2. If you want a different class-slot in a subclass,
you have to specify :ALLOCATION :CLASS in the subclass definition:
(defclass c-2 (c-1)
((s-1 :allocation :class))
(:default-initarg :s-1 4))
should work. The :INITARG and :ACCESSOR options will be inherited and
don't have to be mentioned.
--
Simon.
In article <·····················@athena.mit.edu> ········@athena.mit.edu (Matthew Realff) writes:
>I am new to CLOS and am having the following problem.
There's a separate newsgroup for CLOS, comp.lang.clos. I'm directing
followups there.
>I want to have a class and a subclass with the same slots, bar one or two, which
>should have the same values for all instances of the class, but these values
>should be different for the class and the sub-class.
>
>I tried the following
>
>(defclass c-1 () (s-1 :allocation :class :accessor s-1 :initarg :s-1)
> (:default-initarg :s-1 5))
>
>(defclass c-2 (c-1)
> (:default-initarg :s-1 4))
You need to repeat the slot specification in C-2. A shared slot is shared
by all instances of the class and its subclasses, except those that shadow
it. So you have to do:
(defclass c-2 (c-1) (s-1 :allocation :class :initarg :s-1))
(:default-initarg :s-1 4))
You don't need to repeat the :ACCESSOR option because the inherited
accessor will work. That's because accessors are required to behave
equivalently to calling (slot-value <instance> <slot-name>), and this will
always find the most specific slot.
--
Barry Margolin
System Manager, Thinking Machines Corp.
······@think.com {uunet,harvard}!think!barmar
There are two ways class variables could be implemented in a language.
One way says that the child classes share the class variable of the
parent and the other says that each class implements it.
SmallTalk, CLOS and C++ all implement the former. Your class
variable s-1 is shared. When you create an instance of Class c-1 the
initarg sets the class variable to 5 and when you create the instance
of Class c-2 it gets set to 4. Further, since all instance share
exactly one copy of the instance variable s-1, you can access it
via any instance and get the same value.
I hope this helps.
--
Douglas S. Rand
Internet: <······@mitre.org>
Snail: MITRE, Burlington Road, Bedford, MA
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ
In article <·················@chickpea.mitre.org> ···@chickpea.mitre.org (Douglas S. Rand) writes:
Date: 27 Feb 92 16:29:11 GMT
From: ···@chickpea.mitre.org (Douglas S. Rand)
There are two ways class variables could be implemented in a language.
One way says that the child classes share the class variable of the
parent and the other says that each class implements it.
SmallTalk, CLOS and C++ all implement the former. Your class
variable s-1 is shared. When you create an instance of Class c-1 the
initarg sets the class variable to 5 and when you create the instance
of Class c-2 it gets set to 4. Further, since all instance share
exactly one copy of the instance variable s-1, you can access it
via any instance and get the same value.
You know, many times I've wished for the other option.
Not as a default, mind you. Normal modularity considerations
make the existing behaviour better in most cases.
The typical usage the latter is for tables of all instances of a
particular class.
It's also worth noting that I was surprised by the existing
behaviour. Somehow, it feels more intuitive. The arguments
for not generating new instance variables with each subclass
are somehow subtle and unobvious.
In article <·················@taunton.crl.dec.com> ···@taunton.crl.dec.com (Bob Kerns) writes:
In article <·················@chickpea.mitre.org> ···@chickpea.mitre.org (Douglas S. Rand) writes:
Date: 27 Feb 92 16:29:11 GMT
From: ···@chickpea.mitre.org (Douglas S. Rand)
There are two ways class variables could be implemented in a language.
One way says that the child classes share the class variable of the
parent and the other says that each class implements it.
...
You know, many times I've wished for the other option.
Not as a default, mind you. Normal modularity considerations
make the existing behaviour better in most cases.
The typical usage the latter is for tables of all instances of a
particular class.
Oh. I've wanted the behavior a bunch of times in both CLOS and C++,
but you can always emulate the latter. It's a little worse in C++
where you also have to pay attention to what class's class variable.
--
Douglas S. Rand
Internet: <······@mitre.org>
Snail: MITRE, Burlington Road, Bedford, MA
Disclaimer: MITRE might agree with me - then again...
Amateur Radio: KC1KJ