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 inside the method, the change is applied to the clone, and
the clone is returned.  The caller doesn't need to know about the
cloning, and neither do the already-existing instances of the original
class - they get to keep their copy of the original class.  This
approach preserves the current interface and DWIMery of the class
system, while retaining the benefits of alternative #4.

Since not all languages want to make clones of their classes on
modification (a problem with alternative #4), it's quite easy for that
language's class PMC not to clone itself inside the method, and
instead return a modified version of itself.  In this case, all
instantiated objects would be affected, but this would only be used if
that's the way that language's class system works.

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'()

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, but I imagine it would be minimal,
since classes are generally initialized once and that's it.  If it is
a problem, we could create a shortcut method that takes a list of
attributes to add, or something like that.

--
Alek Storm

Reply via email to