From: Charles Oliver Nutter Date: 2011-10-25T22:24:32+09:00 Subject: [ruby-core:40351] Re: 2.0 feature questionnaire On Tue, Oct 25, 2011 at 7:31 AM, Michal Suchanek wrote: >> Shouldn't local variable encapsulation be sacred? >> >> Get rid of it. > > No, thanks. > > You need to pass variables into blocks. > > Would you have to explicitly declare passed variables? > > That's kind of non-ruby. > > There are very few places where declarations are needed, and adding to > that would be sad. > > While declarations have their place in programming the languages using > them aren't Ruby. > > Yes, Java does, for sure. You totally missed the point. You do know what's meant by "Proc binding", right? I'm not saying to get rid of closed-over variables or require you to declare what variables a block has access to...that would be idiotic. I'm saying a Proc should not be usable as the binding for a subsequent eval. Read my example again. Currently in Ruby, whether you access the local variables from the block or not, anyone can take your block (as a proc) and eval code against it to access all closed-over state: the current object, local variables, constants...everything. It's a big fat encapsulation hole that has the additional bonus of making it much harder to optimize around closed-over variables. And I don't understand why you even bring up Java. Aren't we talking about Ruby here? >> 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. > > Maybe you could go a step further and make auto-freeze the default and > only add a switch to make the bindings non-frozen for compatibility if > somebody really needs that. > > But I do abuse non-frozen bindings regularly. > > When I need an accumulator for results that calculated inside a block > I declare a variable just before the method call that uses the block. > > something like: > > str = "" > > some_stuff.do.something.that.gets.me.an.io{|io| > �� ��begin > �� �� �� ��loop do > �� �� �� �� �� ��str << (io.readpartial READSIZE) > �� �� �� ��end > �� ��rescue EOFError > �� ��end > } Again, you've missed the point. If this "binding" were frozen, your code would not change at all. You don't assign any variables from the enclosing scope...you modify a value in the "str" variable, but the "str" variable itself is never written. And you're not using a "binding" here at all. The binding we're talking about is the one used by eval calls, not normal block/closure variable access. Because every block can be used as an eval binding, it has to carry with it all enclosing state. See my reply above for the long description and re-read my example. - Charlie