On Thu, Jul 22, 2010 at 5:55 AM, Nathan Schneider <nathan@cmu.edu> wrote:
I think a better alternative to allow for safe localization of variables to a block would be to adapt the 'with' statement to behave as a 'let' (similar to suggestions earlier in the thread). For instance:
with fname = sys.argv[1], open(fname) as f, contents = f.read(): do_stuff1(fname, contents) do_stuff2(contents) do_stuff3(fname) # error: out of scope
This makes it clear to the reader that the assignments to 'fname' and 'contents', like 'f', only pertain to the contents of the 'with' block. It allows the reader to focus their eye on the 'important' part—the part inside the block—even though it doesn't come first. It helps avoid bugs that might arise if 'fname' were used later on. And it leaves no question as to where control flow statements are permitted/desirable.
I'm +0.5 on this alternative: my hesitation is because we'd need to explain to newcomers why 'f = open(fname)' would be legal but bad, owing to the subtleties of context managers.
Hmm, an intriguing idea. I agree that the subtleties of "=" vs "as" could lead to problems though. There's also the fact that existing semantics mean that 'f' has to remain bound after the block, so it would be surprising if 'fname' and 'contents' were unavailable. It also suffers the same issue as any of the other in-order proposals: without out-of-order execution, the only gain is a reduction in the chance for namespace collisions, and that's usually only a problem for accidental collisions with loop variable names in long functions or scripts. Cheers, Nick. -- Nick Coghlan | ncoghlan@gmail.com | Brisbane, Australia