From: "Alek Storm" <[EMAIL PROTECTED]>
   Date: Wed, 11 Apr 2007 00:02:29 +0000

   On 4/10/07, Allison Randal <[EMAIL PROTECTED]> wrote:
   > 4) Do away with automatic morphing. Attempting to make changes to a
   > class that's already been instantiated is not allowed (add_method, etc.
   > will throw an exception). This also eliminates the need for
   > remove_method, remove_attribute, remove_role, and remove_parent. To
   > modify a class that has instantiated objects you must clone it first:
   >
   >    classobj = newclass 'Foo'
   >    object = classobj.'new'()
   >
   >    newclassobj = classobj.'clone'('exclude_methods'=>$P1)
   >    newclassobj.'add_method'('bar', $P3)
   >    object2 = newclassobj.'new'()
   >
   > And 'clone' could take an option specifying whether this particular
   > clone will replace the existing class in the namespace. Disadvantage: It
   > eliminates some of the DWIMery of the system. On the other hand, it
   > might make it easier to implement a language that doesn't allow
   > modifications to instantiated classes. (This is currently my favorite
   > alternative.)
   >
   > Allison

   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 . . .

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.

   classobj = newclass 'Foo'
   object = classobj.'new'()

   # add_method returns a clone of the original class with "bar" added
   # C<object> keeps its reference to the original class
   classobj = classobj.'add_method'('bar', $P3)
   object2 = classobj.'new'()

Surely you are not suggesting that any random "add_method" should
require creating a new class?  Did you mean "add_attribute" (or
whatever)?

   The only downside I can think of is the overhead involved in creating
   a new clone of the class for every change to it, for example, when
   many attributes are added at once . . .

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.  The remove_* operations could stay, they would just
throw errors on instantiated classes.

   But in that case, it might be simpler for HLL code to stick to
Allison's original alternative 4, i.e. make an explicit clone, mutate it
as required, and then install it as "the" class returned by find_class.
Error recovery would also be easier for explicit cloning; what happens
if one of the class-mutating methods throws an error?

   Sorry if this is misplaced; I haven't been paying a whole lot of
attention to objects.

                                        -- Bob Rogers
                                           http://rgrjr.dyndns.org/

Reply via email to