bertrand@eiffel.UUCP (Bertrand Meyer) (08/22/89)
From <1318@batserver.cs.uq.oz>, by gjc@batserver.cs.uq.oz (Cumming): > In class STORABLE it appears necessary to use > > object := object_of_same_class.retrieve("filename"); > > instead of > > object.retrieve("filename"); > > Surely the compiler could infer the type of object_of_same_class from the > class of object. The problem was the following. (I am using the past tense because this does not apply to the 2.2 release any more.) The type of `object' is indeed known to the compiler. However any feature call of the form object.anything requires that `object' be in the created state. (Otherwise an exception is triggered.) Hence the obligation to create the object first, and then retrieve it. This was unpleasant for several reasons, one of them being that the Create procedure of the class may require arguments, and have other effects which are not desired if the purpose is just to retrieve a stored persistent structure. The better solution, consistent with the principles of object-oriented software construction, is to work as follows: retrieve_by_name ("filename"); target ?= retrieved Here `retrieve_by_name' is a procedure, not a function. Its effect is to load the stored structure, which is then accessible through the attribute `retrieved'. This is indeed the 2.2 approach. Procedure `retrieve_by_name' takes a filename as argument; there is also `retrieve_by_file' which takes an argument of the Eiffel FILE type, and `retrieve_by_descriptor' which takes an integer representing a Unix file descriptor. These are procedures of class STORABLE; `retrieved' (giving access to the last retrieved structure) is an attribute of that class. Why couldn't this approach be implemented before? The reason was a typing problem. Attribute `retrieved' must be usable for `target' of any possible class type. This implies two facilities, not present in 2.1: - `retrieved' is declared of type ANY. ANY is a universal Kernel Library class; all programmer-defined classes are descendants of that class. - The assignment target := retrieved would not be valid, since it goes against the type rules (the type of the source should conform to, i.e. be a descendant of, the type of the target). The ``Reverse Assignment Attempt'', written target ?= source, will assign to target a reference of the object referred to by `source', but only if the type of that object conforms to the declared type for `target'. Otherwise the effect is to make `target' a void reference. So in most cases the Reverse Assignment Attempt should be followed by if target.Void then ... We didn't get what we expected ... else Got the object requested; proceed. end NOTE: Some readers may have seen the Reverse Assignment Attempt under a previous syntax: `target.Accept (source)'. The form target ?= source was retained as less cumbersome and just as clear. The above is just one way of supporting persistence in 2.2. A more advanced technique uses the ENVIRONMENT Kernel Library class. See the Eiffel Reference Manual for details. -- Bertrand Meyer bertrand@eiffel.com
newbery@Freeport.ira.uka.de (01/29/91)
I understand that in Eiffel you can store an external representation of an object in a file if the object is of class ``storage''. I would like to know a little more about the format of the representation. One simple possibility for such a technique is to store a textual representation of the object. Is this how it is done in Eiffel? or is there a more sophisticated solution. Is a representation of the class itself saved as well or just the representation of the object (supposedly one can load the external representation back in even using another program as long as the class is the same). Many thanks for information or pointers to where I might learn more about this, Frances Newbery Paulisch (newbery@ira.uka.de)