jellinghaus-robert@CS.Yale.EDU (Rob Jellinghaus) (03/19/90)
First, the quick question: what is the deadline for submitting papers
to the Eiffel Users' Group Conference which will be held before TOOLS '90?
I have already missed the TOOLS deadline by a couple of weeks (aargh), but
I'd like to get my paper to the Users' conference if possible... (or is it
the First Eiffel Consortium Conference now?)
Now, my beef. The STORABLE class (which I've dumped on in previous postings)
defines an attribute
retrieved: ANY
which gets inherited by any class inheriting from STORABLE. This seems
wasteful. Any object of a class which inherits from STORABLE will now have
an extra field, most of which will never be used. Consider
class foo export
repeat ANY, ...
inherit STORABLE
feature
...
end -- class foo
If we create many instances of foo, each one will have a "retrieved" attribute
taking up space at runtime. And when one considers that the "retrieved"
attribute only is used after a "retrieve" operation, and that such operations
are unlikely to occur on more than a handful of objects in the system, the
entire scheme seems even more wasteful. Not to mention what happens if the
user has just done something like this:
class ACK export ...
inherit STORABLE, ...
feature ...
retrieve_by_name(...); -- retrieve some huge object and save
-- in Current's "retrieved" feature
store_by_name(...); -- save Current object...
-- AND the just-retrieved object!!!
... end -- class ACK
This means that any use of the STORABLE facilities on the current object runs
the risk of storing objects that you didn't want to store. If I want to
retrieve an object and then store it again, I'd rather do it explicitly!
Why not use the once mechanism? I have implemented things this way in my
store-to-memory class (actually, I didn't do things _exactly_ this way, but
you will get the idea):
class STORABLE_MEMORY export
retrieved
feature
retrieved_value: FIELD[ANY] is
local
tmp_field: FIELD[ANY]
once
tmp_field.Create;
Result := tmp_field
end;
retrieved: ANY is
do
Result := retrieved_value.value
end;
-- the features that actually store and retrieve objects go here
end -- class STORABLE_MEMORY
class FIELD[T] export
value {STORABLE_MEMORY}, set_value {STORABLE_MEMORY}
feature
value: T;
set_value(val: T) is
do
value := val
end
end -- class FIELD[T]
So when my retrieve procedure in class STORED_MEMORY needs to save the object
that it just retrieved, it does
retrieved.set_value(... retrieved object ...)
This scheme works just like the old scheme; it permits one to access the last
retrieved object through the "retrieved" attribute. But it does NOT add an
unnecessary field to all objects inheriting from STORABLE_MEMORY.
I would suggest that ISE consider using this scheme in their STORABLE classes.
If inheritance is to be used as a means to add functionality to objects, the
classes which define that functionality should attempt, as much as possible,
to refrain from defining attributes which will burden all their descendants;
especially when Eiffel is powerful enough to make alternatives possible.
Rob Jellinghaus | "Next time you see a lie being spread or a
jellinghaus-robert@CS.Yale.EDU | bad decision being made out of sheer ignor-
ROBERTJ@{yalecs,yalevm}.BITNET | ance, pause, and think of hypertext."
{everyone}!decvax!yale!robertj | -- K. Eric Drexler, _Engines of Creation_