[Python-Dev] Extended Function syntax

Brett Cannon bac@OCF.Berkeley.EDU
Sun, 2 Feb 2003 14:32:41 -0800 (PST)


[Alex Martelli]

> On Sunday 02 February 2003 11:04 pm, Samuele Pedroni wrote:
> > With Guido's 'do': [notice that count is rebindable in the thunk]
> >
> > class iterclose:
> >   def __init__(self,iterwclose):
> >      self.iter = iterwclose
> >
> >   def __call__(self,thunk):
> >      try:
> >        for x in self.iter:
> >          thunk(x)
> >      finally:
> >        self.iter.close()
> >
> > count = 0
> > do iterclose(open('blah.txt')): (line):
> >    if line.find('Python') >=0:
> >      count += 1
> >      print line,
>
> OK -- I *don't* get that " (line):" part, and how calling thunk() in
> iterclose.__init__ binds/rebinds the local (?) variable line of the thunk.
> Looks like black magic to me.  Guess I must just be a bit thick
> tonight -- sorry.
>

After staring at this for a minute I figured out what ``(line):`` does.
So what you have to realize is that the block (from ``if line...`` to
``print line,`` is passed into ``__call__()`` and bound to ``thunk()``.
Now the object bound to ``thunk`` accepts a single argument, named
``line`` in ``thunk``.  In ``__call__()`` the variable ``x`` is what is
being passed into the thunk code and being bound to ``line``.  Phew.  =)

So, to make sure I am not confuing myself, ``do`` does the
following:

 Instantiates ``iterclose(open('blah.txt'))``.

 Compiles the block of code that makes up the thunk.
	It ends up accepting a single argument which bound to ``line``.

 Calls ``iterclose().__call__(<thunk>)`` and executes it.

 We all let our heads stop spinning from all that and have a good, stiff
drink.  =)

-Brett