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

Reply via email to