--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 &lt;ko1 / atdot.net&gt;:<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(&amp;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>&nbsp; do_stuff...</div><div>end</div><div><br></div><div>define_method :meta do</div><div>&nbsp; do_stuff...</div><div>end.freeze</div><div><br></div><div><br></div><div>Thoughts?</div>
            
--4ea64658_2a79ec49_1124--