Why we will use obj$func() often

Mark Hahn mark at prothon.org
Thu Apr 22 14:20:57 EDT 2004


"Michael Geary" <Mike at Geary.com> wrote ...

>Does anyone have some sample code where obj$func() would be used?
> (Apologies if I missed it.)

There have been so many messages about delegation and binding since Greg
originally posted his meowing cat message that it's hard to remember what
the original problem was that Greg pointed out.  At that time Prothon had no
solution for the problem.  Now there is a released solution but it is
incomplete and has broken the xor operator ( ^ ) (don't tell anyone <grin>).
I'll restate it here in my own way (this is copied from something I posted
on comp.lang.py).

Statement of problem (These are tested programs from released Python and
Prothon:):

# Python

class klass:
    def __init__(self):
        self.me = 1
    def func(self):
        print "func1,self"+str(self.me),

class klass2(klass):
    def __init__(self):
        self.me = 2
    def func(self):
        klass.func(self)        # delegation
        print "func2,self"+str(self.me),

inst = klass2()
inst.func()    # prints  func1,self2   func2,self2

# Directly translated to Prothon

Klass = Object()
with Klass:
    .me = 0            # extra line
    def .__init__():
        .me = 1
    def .func():
        print "func1,self"+.me,

Klass2 = Klass()
with Klass2:
    def .__init__():
        .me = 2
    def .func():
        Klass.func()    # does not do what python does
        print "func2,self"+.me,

inst = Klass2()
inst.func()    # prints  func1,self0  func2,self2

As you can see, the call Klass.func() got the function func from the object
Klass and then called it on Klass using Klass as the target "self" instead
of the instance "inst".  This is not what Python did and this is the
problem.

In Python the call klass.func() was different because Python knows that
klass is a class and therefore obviously cannot be the target of call (an
instance), so it made the programmer pass the instance self to use as a
parameter.

To fix this, we need to be able to specify in general, what the self object
is going to be during the execution of a function in Prothon (I call this
choice of self "binding self to function" even though it's temporary during
execution).

Greg's solution was to replace the period before the function name in
klass.func() with a different symbol to indicate that the func is not
supposed to be bound to klass as the syntax normally suggests (as in
list.sort!()), but instead defaults to the current self.  My final scheme is
almost the same but instead of just defaulting to self, it specifically
forces it to self (this may seem like a semantic difference, but don't say
that to Greg <grin>).

So now we have this solution.  Note that delegation to an ancestor prototype
(class in Python), is a common operation, especially in the __init__
function:

Klass = Object()
with Klass:
    def $__init__():
        $me = 1
    def $func():
        print "func1,self"+$me,

Klass2 = Klass()
with Klass2:
    def $__init__():
        $me = 2
    def $func():
        Klass$func()        # voila!  problem fixed
        print "func2,self"+$me,

inst = Klass2()
inst.func()    # prints  func1,self2   func2,self2








More information about the Python-list mailing list