Alek Storm wrote:
On 4/11/07, Bob Rogers <[EMAIL PROTECTED]> wrote:
I like this one, but I also have another alternative. First, make all
class-modification code (add_method, remove_attribute, etc) return a
PMC*. Whenever one of these methods is called on a class, the class
is cloned . . .
Yeah, this one came up on IRC too. Two problems, first is the
non-obviousness of having a method like 'add_attribute' return a
modified version of the class. The disadvantage of the interface
outweighs the advantage of the DWIM. Second is that the most sensible
return value is some form of error reporting (if exceptions are turned off).
What does "find_class" return after one of these? If it returns the new
class, then there is no need for the class-mutating ops to do so, except
possibly for convenience.
"find_class" returns whatever is currently registered as the class.
Yes. Always true if we were to do automatic cloning. Also true in some
cases of explicit cloning (as a optional feature of 'clone').
Surely you are not suggesting that any random "add_method" should
require creating a new class? Did you mean "add_attribute" (or
whatever)?
I did mean that, but only if the class has already been instantiated.
('add_method' can add an additional multi, for example, so it can modify
existing behavior.)
This is not necessary; you only need to clone the class after the first
time it is instantiated. So you can put an "instantiated_p" flag in the
class to keep track, and keep mutating the same new class until the next
instantiation.
A flag for 'instantiated' is in the new PDD 15 and prototype implementation.
The remove_* operations could stay, they would just
throw errors on instantiated classes.
They could, but how often are people going to add a bunch of attributes
and methods and then remove them immediately before they ever
instantiate the class? The remove_* ops made sense as a feature when
they could be used at any time, but when they only work in a narrow
window it's not worth having them. Especially since we already have to
implement another way (explicit cloning) to dynamically remove
attributes and methods after the class has been instantiated.
Not all languages want to clone their classes on modification. These
languages would use their own class PMCs that don't clone themselves.
They might not clone their classes from the user perspective, but
internally it's the only truly safe way to modify a class that already
has objects instantiated (especially when you're talking about remove
operations). Otherwise, you have objects referencing attributes that
don't exist any longer in the class, or methods referencing attributes
that were never initialized in the object. The closest they can come is
the option 1) I listed.
If one of their classes is passed to and cloned by a different HLL,
their class system will be screwed up/inconsistent. I'm not sure how
requiring HLLs to deal with explicit cloning would be simpler than
having it abstracted away. This system is much more flexible.
The point about abstraction is a good one. It can also be satisfied by
the 'clone' method/vtable. If a class has a different way of handling
modifications, it can return a modified version of itself instead of
returning a new clone (in those cases where the cloning operation was
flagged as a modification of an existing class).
Error recovery would also be easier for explicit cloning; what happens
if one of the class-mutating methods throws an error?
I'm afraid you lost me. How would this be different? Could you
provide some more information?
Essentially, what if you call 'add_method', it automatically clones the
class, and the automatic cloning fails for some reason? Then you get a
mysterious exception about "failed to clone class", leaving the average
user wondering why it was trying to clone a class in the first place.
Allison