Code block literals

Hannu Kankaanp?? hanzspam at yahoo.com.au
Thu Oct 9 08:54:27 EDT 2003


Dave Benjamin <dave at 3dex.com> wrote in message news:<u%0hb.113$_f.1 at news1.central.cox.net>...
> For instance, I always thought this was a cooler alternative to the 
> try/finally block to ensure that a file gets closed (I'll try not to 
> mess up this time... ;) :
> 
> open('input.txt', { |f|
>      do_something_with(f)
>      do_something_else_with(f)
> })

But being a function, it'd have the nasty property of a
separate scope (yes, that can be nasty sometimes). I'd perhaps
want to do

open('input.txt', { |f| data = f.read() })

But alas, 'data' would be local to the anonymous function and
not usable outside. Perhaps I'd want to do this:

open('input.txt', { |f|
    data = f.read()
    return data.startswith('bar')
})

Well, unfortunately that return would only return from the
anonymous function. 'open' could return this result,
so the above could be done awkwardly:

return open('input.txt', { |f|
    data = f.read()
    return data.startswith('bar')
})

But instead for this, and for all the other objects that
require a resource to be freed after it's use, I think a separate
syntax would be preferable (or macros, but we'll never get those).
IIRC, this has been suggested several times before, with
varying syntax:

with f=file('input.txt'):
    data = f.read()
print data[0:3]

That's it. Or for opening multiple files, here's a fabricated example:

with f1=file('1.txt'), f2=file('2.txt', 'w'):
    data = f1.read()
    if data.startswith('foo'):
        break  #break breaks out of 'with'
    f2.write(data)
    return True
print 'bleh'
return False


'with' can't be said to be non-explicit either. It'd be only
used with variables that do have resources to be released, so
what really happens is said clearly. C++ RAII could be considered
implicit on the other hand.

Hmm.. With those 'break' semantics, some might be tempted to use
'with' without any variables as well:

with:
    if x == y:
        x = 1
        break
    x = 0
    if y == z:
        y = 1
        break
    y = 0

In current Python, that'd have to be done like this (or with
a single-element for loop)

if x == y:
    x = 1
else:
    x = 0
    if y == z:
        y = 1
    else:
        y = 0

Hmm, that would lead to two different approaches, which
some might not like. Former is flatter though, at least
if you continue with similar condition/breaks
("Flat is better than nested.") ;)

On a second thought, maybe the break-suggestion was bad
after all. With such break, breaking outside of loop within
'with' wouldn't be so easy. And since 'continue' inside
'with' doesn't make sense, the following would be strange:

for x in range(5):
    with f=file('data%d.txt' % x):
        continue # would continue loop
        break    # would break out of 'with'


Ok, never mind 60% of this message then. Just consider
'with' without break (but with possibility to handle
multiple variables).




More information about the Python-list mailing list