| Chris Page 2004-06-24, 6:33 pm |
| I've often thought that although there is some justification for not
providing a general slot-by-slot object copying function, it would help
to have a more structured way to define such copying when it is needed.
For example, a "copy:" slot option could indicate how to copy instances:
define class <foo> (<object> )
slot s1, copy: #t; // copy the slot
slot s2, copy: #f; // don't copy the slot
slot s3, copy: some-function; // copying function
end;
#t, the default, indicates that the slot is copied either by calling the
slot getter on the source object and then passing the result to the slot
setter on the destination object, or by implementation-defined means
like initialization (I'm not sure which would be best, and perhaps there
should even be another copy: variant to decide which to do.) If the slot
is read-only, the destination slot is set using implementation-defined
means in any case.
#f indicates that the slot is not copied and instead is initialized
using the slot's initialization option. (I'm not sure whether or exactly
when initialize() should be called.)
The third possibility is a function that is passed the source and
destination objects (and perhaps the slot getter or even both
accessors?) and is responsible for copying that slot. A variant of this
is a function that is given the value of the source slot and returns a
value that is assigned to the destination slot. This would make it easy
to supply, e.g., "copy: shallow-copy" to copy the value, but doesn't
provide as much flexibility. I'm not sure which one or whether both of
these options should be allowed. If both are supported it may be
necessary to have different option keywords to distinguish them, similar
to the initialization options.
It may or may not make sense to allow this option for virtual slots.
The "copy:" option would not be allowed for class-allocated slots.
The most likely candidate for implementing these copying options is
probably an implementation-defined shallow-copy() method specialized on
<object>.
For more complicated copying needs, the user would still need to define
a method on shallow-copy(), but they could rely on next-method() to
allocate the new object and to take care of the actions specified by
"copy:" options, similar to the way make() and initialize() work.
This may provide enough structure to make many explicitly-defined
shallow-copy() methods unnecessary, though I am uncertain of that. I am
certain, however, that it would at least make the simpler cases easier
to implement correctly.
Variants for defining deep copying may also make sense.
Interestingly, there appears to be an implementation of a general object
copying protocol with similar features in the FunDev "walker" library:
<http://www.gwydiondylan.org/cgi-bin/viewcvs.cgi/fundev/Sources/lib/walke
r/>
--
Chris Page - Software Wrangler - Dylan Pundit
Open Source Dylan: <http://www.gwydiondylan.org/>
Dylan Blogging: <http://homepage.mac.com/chrispage/iblog/>
|