From: Andrew Dalke Date: 2001-08-08T13:35:16+09:00 Subject: [ruby-talk:19332] Re: Perl/Python/Ruby common backend (Parrot, can Ruby play too?) Phil Tomson wrote: > [...] But I was also referring to the >ability to change built-in classes like Array or Hash for example, I can >add a rotate method to the built-in Array class and everytime I >instantiate an array after that I can call the rotate method on the >instance. I admit to being quite worried about that feature. If that is promoted as common practice, what prevents different packages from making incompatible changes to system functions? I thought that was the point of namespaces - to minimize conflicts between different subsystems. I see the ability to add methods similar to the ability in Python to put things into other modules, including the "__builtin__" module. >>> def f(s): .... return len(s) * 2 .... >>> import __builtin__ >>> __builtin__.len2 = f >>> len2("spam") 8 >>> This is usually seen as bad practice, and I've only seen it used well a couple of times (get_transaction in Zope's ZODB .. and I'm not sure if I fully agree even with that) I learned a couple weeks ago of a reason to be able to add new methods dynamically. I was at a talk where the speaker presented a development system for non-programmers. It allowed them to tweak the class definitions in-place. She chose Tcl (with an object extension) over Python because Python's ability to add new methods is not obvious[*] and because existing instances are not updated with the new class definitions [*] Here are two ways - of many - that would be "obvious" == 1 (backwards compatible) == class Spam: def what(self): print "spam" def Spam.slice(self): print "sliced" == 2 (not backwards compatible, but when I started Python I thought this would work) == class Spam: def what(self): print "spam" class Spam: def slice(self): print "sliced" A third approach perhaps more usable for the aformentioned application would be to have an 'inplace_reload(module)' which tried its best to update an existing module in place - without replacing. For example, by updating the class's Spam.__dict__ and Spam.__bases__. Hmmm... Don't know enough even to make a judgement call. >>change a class's bases...) -- > >Not sure about this one - do you mean that you can change the class's >base class? Python supports multiple inheritence, so change that to "change the class's base classes" and the answer is "yes" >>> class Eggs: .... def what(self): print "I am eggs" .... def scramble(self): print "scrambled" .... >>> class Spam: .... def what(self): print "I am spam" .... def slice(self): print "sliced" .... >>> class SpamAndEggs(Spam, Eggs): .... pass .... >>> food = SpamAndEggs() >>> food.what() I am spam >>> food.slice() sliced >>> food.scramble() scrambled >>> food.__class__.__bases__ (, ) >>> food.__class__.__bases__ = (Eggs, Spam) >>> food.what() I am eggs >>> food.slice() sliced >>> food.__class__.__bases__ = (Eggs,) >>> food.slice() Traceback (innermost last): File "", line 1, in ? AttributeError: slice >>> Andrew dalke@dalkescientific.com