On Wed, Jan 15, 2003 at 01:57:28AM -0500, Dan Sugalski wrote:
> At 9:37 PM -0500 1/14/03, Christopher Armstrong wrote:
> >But who knows, maybe it could be made modular enough (i.e., more
> >interface-oriented?) to allow the best of both worlds -- I'm far too
> >novice wrt Parrot to figure out what it'd look like, unfortunately.
> 
> It'll actually look like what we have now. If you can come up with 
> something more abstract than:
> 
>   callmethod P1, "foo"
> 
> that delegates the calling of the foo method to the method dispatch 
> vtable entry for the object in P1, well... gimme, I want it. :)

> I'll add "define method dispatch more" to the list o' stuff for the 
> next edit of the proposal.

I'll help you along by offering this explanation of how instance
methods work in Python. (sorry if you're already familiar with this
stuff, but it's in my best interest to make sure you are ;-))

When you say something like `o.foo()', it translates into these steps:

 1) LOAD_NAME 'o'
 2) LOAD_ATTR 'bar'
 3) CALL_FUNCTION

#2 has extra magic. What I mean is, when you LOAD_ATTR a function from
a *class*, you just get back a plain old `unbound method'. When you
LOAD_ATTR from an *instance*, and (after failing to find an instance
attribute) the attribute is found on its class, you get a `bound
method', which basically means that Python has "curried" that method
so the first argument is automatically passed -- that first argument
is the instance which you LOAD_ATTRd from. This is why you see all
those python methods with the first argument being `self', and rarely
see code which explicitly passes that first argument.

Now, like I said, this magic is done in LOAD_ATTR, not CALL_FUNCTION,
so you can take that bound method object and do whatever you want with
it before calling it.

Here's an interesting code snippet which also demonstrates the fact
that methods are just attributes.

>>> def toot(): print "hello"
... 
>>> class Foo: pass
... 
>>> # binding a method *to the instance* -- this prevents magic
>>> o = Foo(); o.toot = toot 
>>> o.toot()
hello
>>> # binding method *to the class* -- just the same as if we defined
>>> # `toot' in the class definition
>>> Foo.toot = toot 
>>> o2 = Foo()
>>> o2.toot()
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: toot() takes no arguments (1 given)

That traceback happened because, as I explained above, when the `toot'
attribute was LOAD_ATTR'd from the instance and found on the class, it
was turned into a bound method that would have the instance
automatically passed to it.

HTH,

-- 
 Twisted | Christopher Armstrong: International Man of Twistery
  Radix  |          Release Manager,  Twisted Project
---------+     http://twistedmatrix.com/users/radix.twistd/

Reply via email to