Ruby blocks in Python, a suggestion

From: Ville Vainio (ville_at_spammers.com)
Date: 04/07/04


Date: 07 Apr 2004 08:40:42 +0300

I participated in a short thread on c.l.ruby, and had myself convinced
that "blocks" might be a good idea. For bragging rights, if nothing
else :).

What I'm talking about is:

<callable> block [<block args>]:
    suite

<callable> would be called with one argument, 'block', which it could
execute via normal calling (or call, or execute, or whatever).

i.e.

class with_open_file:
  def __init__(self, *args):
    self.args = args
  def __call__(self, block):
    f = open(*self.args)
    try:
      block.call(f) # f is passed to the "block argument"
    finally:
      f.close()

def somefunc():
  x = 10
  with_open_file("a.txt","r") block(f): # assigns f to the opened file
    x = len(f.read()) # rebinds x!

Note that block would be executed with the same bindings as
somefunc(), not its lexically closed bindings that would be the case
if the actions within block were in a normal function.

Other examples:

transaction(dbconn) block(t): # commit/rollback t based on exception status
  t.dostuff()

foreach([(1,2), (2,4), (3,6)]) block(x,y):
  assert y == X*2

mapseq(seq) block(entry, result):
  result.append(entry * 2)

Obviously this functionality could be quickly hacked by making the
bindings of "block parameters" function-global just like the variable
in for loops (and LC's in the current implementation). Even if only
block-visible fucntionality would be so much cooler.

And yes, I know this blocks issue has been hashed over previously. I'm
just too busy to google for it right now, and just wanted to get this
off my chest quickly :-).

-- 
Ville Vainio   http://tinyurl.com/2prnb