----- Original Message -----
From: "Brian Candler" <B.Candler / pobox.com>
To: "ruby-talk ML" <ruby-talk / ruby-lang.org>; <hal9000 / hypermetrics.com>
Cc: "ruby-talk ML" <ruby-talk / ruby-lang.org>
Sent: Wednesday, February 12, 2003 5:50 PM
Subject: Re: Lexical scope and closures


> > I didn't realize that. So we ARE breaking
> > old code, eh?
>
> Yes. That's one reason for the warning; the other reason is because Matz
> finds the practice of 'shadowing' distasteful :-)

<sigh> I never really understood the term "shadowing." I thought
he meant that a local assignment inside a block resulting in a
redefinition was distasteful. Apparently that's the exact opposite
of what he meant.

What happens to the case where obj has a meth= method, and
we put obj.meth between vertical bars?

And how will I save the value of an iterated variable? Will I have
to assign it to a var in the outer scope as soon as I enter the
block?

> It will also break old code where it depends on a variable introduced in a
> block being local, e.g.
>
>    Thread.new {
>      i = 0
>      ... use i locally
>    }
>
> I don't remember seeing a warning for this situation being discussed, but
it
> would seem logical to do so.

Hmm, even more confusing. But perhaps you could simply add
your block-local variable(s) to the list:  Thread.new {|i|...

> What you gain: probably less surprising behaviour. "a = 0" always binds to
> the method scope (whether or not it is inside a block), and "|a|" is
always
> block-local (whether or not 'a' has been used before).

Less surprising, but an imperfect solution IMO.

Still, none of the solutions has seemed perfect to me.

It seems that Matz's INVIOLABLE rule is to keep Ruby
declarationless. Every solution I saw (I think) that
kept all functionality involved some kind of declaration
mechanism.

Hal