eieio.el: shared-initialize: question about intended behavior
Jan Moringen <[email protected]> Sun, 01 Feb 2009 03:10:33 +0100
| Newsgroups | gmane.emacs.eieio |
|---|---|
| Message-ID | <20165_1233454237_ZZg0m1id4iBh7.00_1233454233.3317.17.camel@localhost.localdomain> |
Hi,
I wrote a class, rudel-delete, which behaves as if it had three
slots, :from, :to and :length. The slot :length is virtual in the sense
that it is entirely realized through `slot-missing'. Here is the code:
(defclass rudel-delete (rudel-operation)
((from :initarg :from
:type (integer 0)
:documentation
"Start of the region affected by this operation.")
(to :initarg :to
:type (integer 0)
:documentation
"End of the region affected by this operation."))
"Delete a region.")
(defmethod slot-missing ((this rudel-delete)
slot-name operation &optional new-value)
"Simulate slot :length"
(cond
;; Slot :length
((or (eq slot-name :length)
(eq slot-name 'length))
(with-slots (from to) this
(if (eq operation 'oref)
(- to from)
(setq to (+ from new-value)))))
;; Call next method otherwise
(t (call-next-method)))
)
The code works for the case where the value of :length is deduced in an
object that has been initialized with :from and :to. However, when
trying to initialize an instance with :from and :length, something goes
wrong. From the resulting stacktrace and state of the half-initialized
object, the problem seems to be that `slot-missing' is called twice. The
first call correctly sets :to to the value deduced from :length
and :from. The second call to `slot-missing' has the slot symbol bound
to nil.
I looked into `initialize-instance' (in eieio.el) and probably
identified the reason for the described behavior:
(let ((rn (eieio-initarg-to-attribute (object-class-fast obj)
(car slots))))
(if (not rn)
- (slot-missing obj (car slots) 'oset (car (cdr slots))))
- (eieio-oset obj rn (car (cdr slots))))
+ (slot-missing obj (car slots) 'oset (car (cdr slots)))
+ (eieio-oset obj rn (car (cdr slots)))))
The original `if' expression terminates after the call to `slot-missing'
such that `eieio-oset' is called unconditionally, even when rn is nil.
The above change makes the problem go away and makes the behavior more
logical in my opinion.
However, since I am not completely sure what the intended behavior is, I
would rather ask than breaking the very core of the object system ;)
Kind regards,
Jan Moringen
------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword