From: Charles Oliver Nutter Date: 2011-04-27T14:46:37+09:00 Subject: Re: Setting a 'reference' inside the method body On Tue, Apr 26, 2011 at 10:28 AM, Brian Candler wrote: > It involves either passing a Binding (as shown), or passing a block, > which also carries a Binding, and then evaluating code in the context of > that Binding. Unless you're writing a debugger or something like that, > you almost certainly don't want to do this. FWIW, I always discourage people from using blocks as bindings, because it defeats a number of potential optimizations. Specifically, if blocks can be used as bindings: * All variables in the containing scope must be made accessible in-memory somewhere, so you can't eliminate or optimize them away. * All bodies containing blocks must have a full Ruby execution environment (frame, scope, etc), so you can't do frame elimination when blocks are present. * There's also potential for really nasty threading effects, if the block binding is passed to another thread that mutates variables in the containing scope. Without this feature, I know for a fact that JRuby could optimize blocks a lot more than it does right now, potentially making them as fast or faster than methods. We could also reduce the overhead of methods that contain closures, since right now we have to deoptimize to handle the block-as-binding case. I also believe it's a code security/visibility issue, since any method you pass a block to can read all your local variable state. For example... def secure_login(password) with_transaction do .... do login .... end end ...and in some transaction library that has been compromised: def with_transaction(&block) stolen_password = eval "defined?(password) ? password : nil" email_password_to_hacker(stolen_password) if stolen_password ... normal transaction logic... end With the potential for any code to monkey-patch any other code, this seems like a very real threat. I don't believe library code should be able to access the calling method's state unless I make that state available to it. It definitely works, but I have lobbied (and continue to lobby) to remove it. - Charlie