Perl/Python/Ruby common backend (Parrot, can Ruby play too?)
Andrew Dalke
dalke at acm.org
Tue Aug 7 08:09:07 EDT 2001
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__
(<class __main__.Spam at 1071fa0>, <class __main__.Eggs at 10702a0>)
>>> food.__class__.__bases__ = (Eggs, Spam)
>>> food.what()
I am eggs
>>> food.slice()
sliced
>>> food.__class__.__bases__ = (Eggs,)
>>> food.slice()
Traceback (innermost last):
File "<interactive input>", line 1, in ?
AttributeError: slice
>>>
Andrew
dalke at dalkescientific.com
More information about the Python-list
mailing list