Created
February 26, 2014 02:55
-
-
Save obriencj/9222665 to your computer and use it in GitHub Desktop.
Examples of compile/eval not giving me a chance to provide lexical bindings for it to snag closures from
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def attempt_1(): | |
data = list() | |
# no prob, bob. data is captured as a closure cell of action | |
action = lambda x: data.append(x) | |
action(5) | |
return data | |
def attempt_2(): | |
data = list() | |
# lambda is compiled without any outer lexical bindings, so it | |
# can't find a `data` to capture, so it presumes it must be a | |
# global... | |
src = "lambda x: data.append(x)" | |
code = compile(src, '<none>', 'eval') | |
action = eval(code, globals(), locals()) | |
# boom. data wasn't in globals, it was in locals. the action never | |
# thought to look in locals, so it a-splodes | |
action(5) | |
return data | |
def attempt_3(): | |
data = list() | |
# here we'll promise to provide data later | |
src = "lambda data: lambda x: data.append(x)" | |
code = compile(src, '<none>', 'eval') | |
# then we have to fulfil that promise before we can actually use | |
# the lambda we wanted. | |
action = eval(code, globals(), locals())(data) | |
action(5) | |
return data | |
print("attempt_1", attempt_1()) | |
try: | |
print("attempt_2", attempt_2()) | |
except Exception as e: | |
print("attempt_2", e) | |
print("attempt_3", attempt_3()) | |
# The end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
These are obviously contrived simple examples meant to illustrate the point.