On Wed, Feb 05, 2003 at 10:23:52PM +0900, dblack / candle.superlink.net wrote:
> Originally, the problem was shadowing.  As I understood it, the reason
> this was a problem:
> 
>    def meth(arr)
>      x = 0
>      arr.each {|x| ... }
>      p x                  # arr[-1]
>    end
> 
> was that people wanted to be able to write blocks, and move them
> around the code physically, without worrying about what came before
> and after them.  The need to do refactoring without renaming variables
> has been mentioned in this connection.

Just to be clear, I think what we want is the ability to write blocks
that can be moved without affecting the code around them.  That's
different from not having any blocks affect the code around them.

> OK....  That's a good argument for having |x| be local to the block.

I disagree.  It's a good argument for any of the solutions to the
problem that were voted for on Rubygarden.

> But then if we're also trying to accomodate this:
> 
>   def meth(arr)
>     arr.each {|x| y = x }
>     p y
>   end
> 
> we're now focusing on having blocks work in such a way that they *do*
> interact with what's around them.  And if one argues that the block
> *and* the "p y" could be moved around together during refactoring --
> well, so could "y = nil", etc....

Yes, we want to be able to do both.  If the block can't interact with
its environment, then Ruby ceases to have closures (and that would not
be an insignificant loss).

I'm not going to argue that the code you gave can be moved around
without thinking about the code around it, but the following can:

  def meth(arr)
    local do |y|
      arr.each {|x| y = x }
      p y
    end
  end

Paul