Prev: Fascinating interview by Richard Stallman on Russia TV
Next: instructor solution manual for Introduction to Quantum Mechanics 1st edition (1995) by David J. Griffiths
From: jimka on 8 Jul 2010 09:45 Does anyone have advise for the strategy for writing methods on update- instance-for-different-class for the case of multiple inheritance. For example suppose we have the following: ;; library code (defclass A () ((a))) (defclass B () ((b))) (defclass C () ((c))) ;; application code (defclass X (A B C) ()) (defclass Y (A C) ()) ;; application code (let ((i (make-instance 'Y))) (change-class i 'X)) (let ((i (make-instance 'X))) (change-class i 'Y)) In the first case Y --> X the instance is gaining B'ness so this promotion code can be handled in the update-instance-for-different-class specializing its second argument on class B ;; promotion handler (defmethod update-instance-for-different-class (previous (current B) &rest initargs) ...) In the second case X --> Y the instance is going to keep its A'ness and C'ness but loose its B'ness. Thus this is sort of a class "demotion". It appears I can put this handling in the update-instance-for-different-class method whose first argument specializes on B. ;; demotion handler (defmethod update-instance-for-different-class ((previous B) current &rest initargs) ...) There are several things I don't understand about this strategy. 1. Both methods will be called in the case when the old and new classes BOTH have B in their class precedence list. So these methods do handle the promotion and demotion but not exclusively so. 2. Should I be adding primary methods who call call-next-method, or should I be adding before/after methods or does it matter? 3. In the case of update-instance-for-redefined-class, the system passes me structures containing the added and deleted slots. How am I supposed to get the similar information in the case of update-instance-for-different-class? 4. Can I really hope to handle all the change-class cases based on methods specialzin4 on the library classes, A, B, and C, or is it really necessary to expect the application programmer to handle these by adding methods of update-instance-for-different-class specialing on X and Y? Advise from anyone who had done this would be great to have. -jim
From: jimka on 14 Jul 2010 17:14 i think nobody likes update-instance-for-different-class :-(
From: Pascal Costanza on 15 Jul 2010 06:30
On 08/07/2010 15:45, jimka wrote: > Does anyone have advise for the strategy for writing methods on update- > instance-for-different-class for the case of multiple inheritance. > For example suppose we have the following: > > ;; library code > (defclass A () > ((a))) > > (defclass B () > ((b))) > > (defclass C () > ((c))) > > > ;; application code > (defclass X (A B C) > ()) > > (defclass Y (A C) > ()) > > ;; application code > (let ((i (make-instance 'Y))) > (change-class i 'X)) > > (let ((i (make-instance 'X))) > (change-class i 'Y)) > > In the first case Y --> X the instance is gaining B'ness so this > promotion code can be handled > in the update-instance-for-different-class specializing its second > argument on class B > > > ;; promotion handler > (defmethod update-instance-for-different-class (previous (current B) > &rest initargs) > ...) > > > In the second case X --> Y the instance is going to keep its A'ness > and C'ness > but loose its B'ness. Thus this is sort of a class "demotion". It > appears I can put > this handling in the update-instance-for-different-class method whose > first argument > specializes on B. > > > ;; demotion handler > (defmethod update-instance-for-different-class ((previous B) current > &rest initargs) > ...) > > > There are several things I don't understand about this strategy. > > 1. Both methods will be called in the case when the old and new > classes BOTH have > B in their class precedence list. So these methods do handle the > promotion and demotion > but not exclusively so. > > 2. Should I be adding primary methods who call call-next-method, or > should I be adding before/after methods or does it matter? To answer such questions, it is important to consider the purpose of update-instance-for-different-class. It is part of the various ways to initialize objects, like initialize-instance and reinitialize-instance. You typically define methods on initialize-instance and reinitialize-instance to have more complicated initializations of slots than what you can do with just initargs and initforms. It is also typically suggested to defined :after methods, both for efficiency and for ensuring that the object is already "mostly" initialized. There is actually wording in the description of update-instance-for-different-class that also "recommends" defining :after methods here as well, so this seems to confirm what I say. Usually, I expect update-instance-for-different-class to be specialized only on its second argument, and use it to only make such complicated initializations of newly added slots. Then different methods for u-i-f-d-c will also not interfere with each other. It's probably also worthwhile to consider defining methods on shared-initialize instead, unless it really matters. > 3. In the case of update-instance-for-redefined-class, the system > passes me structures containing the added and deleted slots. How am I > supposed to get the similar information > in the case of update-instance-for-different-class? The first argument to u-i-f-d-c contains a complete copy of the previous version of the object to be updated, so you should be able to get all the necessary information from there. > 4. Can I really hope to handle all the change-class cases based on > methods specialzin4 > on the library classes, A, B, and C, or is it really necessary to > expect the application programmer to handle these by adding methods of > update-instance-for-different-class specialing on X and Y? The hope is that every class designer cares about their classes, so you should only need to define methods for your 'own' classes. > Advise from anyone who had done this would be great to have. I don't think the u-i-f-d-c is used a lot, especially because it is recommended that change-class is not used very often (see the description for change-class). So I fear that you will likely encounter problems in this regard when you really want to use change-class with third-party classes. But I haven't done a lot with u-i-f-d-c either. Best, Pascal -- My website: http://p-cos.net Common Lisp Document Repository: http://cdr.eurolisp.org Closer to MOP & ContextL: http://common-lisp.net/project/closer/ |