Well it's a bit of a design trade off. If you have a non-persistent base class, should the semantics of the slot storage change based on whether it's included in a persistent subclass? Currently the policy is simple; persistence is determined by annotations on direct slots and not effective slots. Thus you can get functional inheritance, but have to manually specify if you want to persist an inherited non-persistent subclass.
To get persistent behavior for non-persistent base classes you need to explicitly tell the CLOS protocol that a slot is persistent and the only way to do that today is to include the base class slots directly in the superclass. You'll still get the base class generic function dispatch, but reads/writes will go to the persistent store instead of memory. (defclass foo () ((myfoo) (bar))) (defclass sub-foo (foo) ((bar) (baz)) (:metaclass ele:persistent-metaclass)) Thus myfoo is transient and bar, baz are persistent. (defmethod mutate-bar ((obj foo) value) (setf (slot-value obj 'bar) value)) This will set the persistent value of bar for objects of sub-foo, but set the in-memory value of bar if the object is of type 'foo'. It is possible to do this automatically by modifying the Elephant metaclass protocol, perhaps with a class option or a new metaclass 'inheriting-persistent-metaclass' which defaults to making all subclass slots persistent...then to override this behavior you'd special case subclass slot names by specifying transient in a shadowing subclass definition. (defclass foo () ((myfoo) (bar))) (defclass sub-foo (foo) ((baz) (myfoo :transient t)) (:persist-subclass-slots t) (:metaclass ele:persistent-metaclass)) This would have identical behavior to the first example, but you don't have to make myfoo transient (it would then be given a persistent type for sub-foo). Now what happens if we inherit from sub-foo above? (defclass sub-sub-foo (sub-foo) ((qux)) (:metaclass ele:persistent-metaclass)) ;; protocol will assert an error if subclass of persistent isn't persistent In this case the normal CLOS machinery will pick up the non-direct slots from subclasses and the bar and myfoo slots will be non-transient. There may be a way to override this to search for subclass specifications of :persist-subclass-slots and then go ahead and promote :transient effective slots to :persistent but all the cases and interactions can start to become hairy. I think the currently policy is the simplest and least bug prone, even though it forces the increased verboseness of the first example. Thoughts? Ian Pierre THIERRY wrote: > I'm happily using Elephant in a Web-based project right now, but I'm > getting annoyed by the behoviour of Elephant WRT inheritance. The > problem is that only direct slots of the class with the persistent > metaclass as metaclass are made persistent. > > If I have the following classes: > > (defclass foo () > ((bar))) > > (defclass sub-foo (foo) > ((baz)) > (:metaclass ele:persistent-metaclass)) > > Only the baz slot will be persistent. Is it impossible to gain advantage > of both inheritance and persistence, or am I missing something? > > Curiously, > Nowhere man > > ------------------------------------------------------------------------ > > _______________________________________________ > elephant-devel site list > elephant-devel@common-lisp.net > http://common-lisp.net/mailman/listinfo/elephant-devel _______________________________________________ elephant-devel site list elephant-devel@common-lisp.net http://common-lisp.net/mailman/listinfo/elephant-devel