Re: eieio.el: shared-initialize: question about intended behavior
"Eric M. Ludlam" <[email protected]> Sun, 1 Feb 2009 08:46:08 -0500
| Newsgroups | gmane.emacs.eieio |
|---|---|
| Message-ID | <[email protected]> |
I agree with your deduction, especially since there is no test in eieio-tests.el for this particular use of slot-missing. It would be great if you could check in this change. It would be even better if there were also a couple tests. Thanks! Eric >>> Jan Moringen <[email protected]> seems to think that: >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