[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Semantics of :initform and oset-default
From: |
Eric Ludlam |
Subject: |
Re: Semantics of :initform and oset-default |
Date: |
Mon, 09 Feb 2015 08:06:21 -0500 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 |
On 02/08/2015 09:48 PM, Stefan Monnier wrote:
Hi Eric,
I have some questions about the default values of object slots:
- The Texinfo docs say:
[...]
The value passed to initform is automatically quoted. Thus,
:initform (1 2 3)
appears as the specified list in the default object. A symbol that
[...]
this seems to say that :initform is really an init*value*. But then
in eieio-tests.el we have:
(defclass inittest nil
((staticval :initform 1)
(symval :initform eieio-test-permuting-value)
(evalval :initform (symbol-value 'eieio-test-permuting-value))
(evalnow :initform (symbol-value 'eieio-test-permuting-value)
:allocation :class)
)
"Test initforms that eval.")
(ert-deftest eieio-test-21-eval-at-construction-time ()
;; initforms that need to be evalled at construction time.
(setq eieio-test-permuting-value 2)
(setq eitest-pvinit (inittest))
(should (eq (oref eitest-pvinit staticval) 1))
(should (eq (oref eitest-pvinit symval) 'eieio-test-permuting-value))
(should (eq (oref eitest-pvinit evalval) 2))
(should (eq (oref eitest-pvinit evalnow) 1)))
which gives a different picture, and I don't really understand it: in
the `symval' slot the :initform seems to be quoted (as documented),
but in the other two (`evalval' and `evalnow') the :initforms are
actually evaluated.
Hi Stefan,
Originally eieio only had an initvalue as you named it above because I
didn't get what was supposed to happen with the initform, and I had a
lame lambda form for cases where you might want to evaluate the form at
construction time. The doc may not have been updated correctly when I
tried to make eieio more CLOS compatible based on the feedback I was
getting.
It was pointed out that the initform is supposed to be evaluated so
there is a bit of a hybrid behavior which allows:
:initform "string"
which would work regardless of how/when things are evaluated. It also
enables the very old eieio behavior:
:initform (1 2 and other constants) ;; No quote needed
and also what a CLOS user might expect:
:initform '(1 2 and other constants) ;; same end result as above
plus function evaluation:
:initform (symbol-value 'some-variable)
which is in the test you quoted.
The logic is up in `eieio-default-eval-maybe'.
The 'evalnow, and 'evalval slots in the test differ based on when they
get evaluated.
A slot with :allocation :instance (the default) would have the form
evaluated when it is constructed. A slot with :allocation :class is
evaluated when the class is created. If just the symbol is in there, it
acts as a constant value (ie - no function form to call)
- How is it supposed to interact with oset-default? Is the value passed
to `oset-default' interpreted as a plain value (to which the slot
will always be initialized), or is it interpreted as a "maybe
value maybe expression to be evaluated", like the :initform?
oset default doesn't have anything special around when the VALUE
argument is evaluated, so that form is evaluated the way arguments to
other functions are evaluated.
If you wrote:
(oset-default 'myclass someslot '(symbol-value 'moose))
then the first quote would be 'evaluated' sticking the form
(symbol-value 'moose) into the initform for that slot. Then at
instantiation time, the symbol value of moose would be calculated and
stuck in as the slot value. ie:
ELISP> (setq moose 1)
1
ELISP> (oset-default 'foo test '(symbol-value 'moose))
(symbol-value 'moose)
ELISP> (foo "hi")
[object foo "hi" 1]
I don't know if that is correct or not. It didn't occur to me that you
could do that until I tried explaining just now.
Here is the documentation I had used at the time:
http://www.lispworks.com/documentation/HyperSpec/Body/m_defcla.htm
and the key bit of text:
> The :initform slot option is used to provide a default initial value
> form to be used in the initialization of the slot. This form is
> evaluated every time it is used to initialize the slot.
It goes on to talk about the lexical environment which I didn't/don't
know how to deal with.
I hope this helps.
Eric