--4ea64658_2a79ec49_1124 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline On Monday, October 24, 2011 at 10:29 PM, Charles Oliver Nutter wrote: > 2011/10/1 SASADA Koichi <ko1 / atdot.net (mailto:ko1 / atdot.net)>: > > - Remove Proc binding > > I added this one. Anyone who has ever attempted to optimize Ruby knows > this is one of the biggest roadblocks. If any time, any local state > can be seen by code you've passed a block to, you can't optimize any > of that code in a way that would make it inaccessible. > > I'd also argue it breaks encapsulation in the same awful way that "retry" did: > > def foo > password et_password > transaction do > service.auth(password) > service.do_something > end > end > > ... > > def transaction(&block) # my evil patch > steal_password eval('password', block) > end > > Any library that can patch "transaction" can see the "password" local. > Shouldn't local variable encapsulation be sacred? > > Get rid of it. I've had an alternate idea to accomplish something like a compromise, but I'm still a ways away from having anything like a patch. The idea is this: make Proc#freeze snapshot all bindings. Essentially, telling a Proc to freeze would cause all bindings in the proc to be evaluated and replaced with their value at that moment. These values, themselves, would then be frozen, and references to the original code blocks could be released. Requiring an extra method call to accomplish this is slightly inconvenient, but it would keep Ruby 2.0 "backwards compatible" (in quotes because really? does anybody sensible actually abuse proc bindings like this?). The hope would be that eventually everyone would get into the habit of freezing their procs and eventually this could become the default behavior. I have to admit I haven't had a chance to completely work through all the details of this idea yet. I will say that my ultimate hope is that the following two methods would be equivalent with the same performance in Ruby 2.0: def traditional do_stuff... end define_method :meta do do_stuff... end.freeze Thoughts? --4ea64658_2a79ec49_1124 Content-Type: text/html; charset="utf-8" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline <div><span class="Apple-style-span" style="color: rgb(160, 160, 168); ">On Monday, October 24, 2011 at 10:29 PM, Charles Oliver Nutter wrote:</span></div> <blockquote type="cite" style="border-left-style:solid;border-width:1px;margin-left:0px;padding-left:10px;"> <span><div><div>2011/10/1 SASADA Koichi <ko1 / atdot.net>:<br><blockquote type="cite"><div>- Remove Proc binding<br></div></blockquote><br>I added this one. Anyone who has ever attempted to optimize Ruby knows<br>this is one of the biggest roadblocks. If any time, any local state<br>can be seen by code you've passed a block to, you can't optimize any<br>of that code in a way that would make it inaccessible.<br><br>I'd also argue it breaks encapsulation in the same awful way that "retry" did:<br><br>def foo<br> password = get_password<br> transaction do<br> service.auth(password)<br> service.do_something<br> end<br>end<br><br>...<br><br>def transaction(&block) # my evil patch<br> steal_password eval('password', block)<br>end<br><br>Any library that can patch "transaction" can see the "password" local.<br>Shouldn't local variablencapsulation be sacred?<br><br>Get rid of it.</div></div></span></blockquote><div><br></div><div>I've had an alternate idea to accomplish something like a compromise, but I'm still a ways away from having anything like a patch.</div><div><br></div><div>The idea is this: make Proc#freeze snapshot all bindings.</div><div><br></div><div>Essentially, telling a Proc to freeze would cause all bindings in the proc to be evaluated and replaced with their value at that moment. These values, themselves, would then be frozen, and references to the original code blocks could be released. Requiring an extra method call to accomplish this is slightly inconvenient, but it would keep Ruby 2.0 "backwards compatible" (in quotes because really? does anybody sensible actually abuse proc bindings likehis?). The hope would be that eventually everyone would get into the habit of freezing their procs and eventually this could become the default behavior.</div><div><br></div><div>I have to admit I haven't had a chance to completely work through all the details of this idea yet. I will say that my ultimate hope is that the following two methods would be equivalent with the same performance in Ruby 2.0:</div><div><br></div><div><br></div><div>def traditional</div><div> do_stuff...</div><div>end</div><div><br></div><div>define_method :meta do</div><div> do_stuff...</div><div>end.freeze</div><div><br></div><div><br></div><div>Thoughts?</div> --4ea64658_2a79ec49_1124--