Local variables & blocks

Can someone list a synopsis of the new rules (or have I missed that?)
This thread got to be wayyyy too long to follow for me with all the
points and counterpoints.

(1) Block parameters - e.g. |i,j| - are always local to the block,
regardless of whether a variable with the same name already exists. e.g.

  i = 0
  [1,2,3].each { |i| # this is a *different* i (shadowing)
    puts i
  }
  puts i

will print 1 2 3 0

I think Matz wants a compulsory warning if you shadow a variable in this way
(i.e. generated even if you don't specify '-w')

(2) Other assignments are always bound to the method's main local variable
scope, whether or not it already exists. For example:

  [1,2,3].each { |i|
    j = i
  }
  puts j

will print '3', and

  [1,2,3].each { |i|
    j = i if i > 3
  }
  puts j

will print 'nil'. The same behaviour is achieved in the current version of
Ruby if you put 'j = nil' before the loop.

So two distinctions will no longer exist:

- block parameters are local or bound?
    => they are always local
- variables defined within a block are local or bound?
    => they are always bound

Under the current rules, in both cases they are 'bound' if an assignment to
a variable of the same name occured anywhere before the block, and 'local'
if not.

Regards,

Brian.

Please justify why this warning is necessary. The code you give above
is elegant. The proposed rules make it clear what is meant, and it
satisfies my POLS. Why is a warning generated?

OTOH, I would expect a warning for this code:

i = 0
[1,2,3].each { |i|
i = 7
}
puts i

But that code is clearly garbage anyway, old or new rules.

Gavin

···

On Wednesday, February 5, 2003, 1:47:47 AM, Brian wrote:

(1) Block parameters - e.g. |i,j| - are always local to the block,
regardless of whether a variable with the same name already exists. e.g.

i = 0
[1,2,3].each { |i| # this is a different i (shadowing)
puts i
}
puts i

will print 1 2 3 0

I think Matz wants a compulsory warning if you shadow a variable in this way
(i.e. generated even if you don’t specify ‘-w’)

Gavin Sinclair wrote:

[…]

I think Matz wants a compulsory warning if you shadow a variable in this way
(i.e. generated even if you don’t specify ‘-w’)

Please justify why this warning is necessary. The code you give above
is elegant. The proposed rules make it clear what is meant, and it
satisfies my POLS. Why is a warning generated?

Essentially, the warning ends up saying: The scoping rules are improved
now, but everybody must pretend they are not.

The fix is one I’ve hoped for for a long time, exactly because I don’t
want to worry over the naming of parameters. But in the end, compulsive
warnings defeat that purpose.

Block parameters fill the role of natural language’s common pronouns,
not its proper nouns. Please make the warnings optional so we can use
them that way.

Mark

At very least, this will catch some typos in assignment statements, and it

not its proper nouns. Please make the warnings optional so we can use
them that way.

You don't think that it exist a problem when someone ask for warnings
and another person just want remove these same warnings.

Guy Decoux

I was asking for something different, and I'm sorry if I wasn't clear.

(1) Matz wants a compulsory warning here:

  foo = 0
  [1,2,3].each { |foo| # << HERE
    ..
  }

Myself, and several others on this list, feel that this warning should be
optional. It's not really necessary at all, unless you're concerned about
making your scripts run on earlier versions of Ruby.

(2) I asked for a warning (optional, with -w) if a local variable is
assigned but not used. Examples would be:

  foob = 0 # << HERE
  puts foo
  ... and no subsequent use of 'foob'

OR:

  foo = 1 # << HERE
  if status = "OK"
    foo = 2
  end
  puts foob
  ... and no subsequent use of 'foo'

In both cases, a (method) local variable has been brought into play and
assigned to, but the value not used - either because the assignment was
misspelled, or all uses of it were misspelled.

This request can be considered entirely separately from the block-scoping
issue. It would incidentally catch a few perverse cases, for example

  i = 0
  ...
  [1,2,3].each { |i|
     i = 7 # << HERE, this value is never retrieved
  }

Regards,

Brian.

···

On Wed, Feb 05, 2003 at 03:03:24AM +0900, ts wrote:

> At very least, this will catch some typos in assignment statements, and it

> not its proper nouns. Please make the warnings optional so we can use
> them that way.

You don't think that it exist a problem when someone ask for warnings
and another person just want remove these same warnings.

ts wrote:

“B” == Brian Candler B.Candler@pobox.com writes:

not its proper nouns. Please make the warnings optional so we can use
them that way.

You don’t think that it exist a problem when someone ask for warnings
and another person just want remove these same warnings.

Guy Decoux

Is that not why we have -w? Use it and you get extra guidance in the
form of warnings; don’t use it, and the reasonable assumption is that
you’ve done some testing/debugging and are comfortable with a given
piece of code.

Anybody who wants the extra warnings can have them. What’s the problem?

Mark

···

At very least, this will catch some typos in assignment statements, and it > > > >>>>>>“M” == Mark Slagell ms@iastate.edu writes:

Oh and just to be clear, I'm not asking for any sort of data-flow analysis;
just a trivial check that at least one access has been made.

  [1,2,3].each { |i|
     puts i # value of 'i' is used (usage count > 0)
     i = 7 # so no warning here
  }
    
Regards,

Brian.

···

On Tue, Feb 04, 2003 at 07:28:26PM +0000, Brian Candler wrote:

This request can be considered entirely separately from the block-scoping
issue. It would incidentally catch a few perverse cases, for example

  i = 0
  ...
  [1,2,3].each { |i|
     i = 7 # << HERE, this value is never retrieved
  }

Hi,

(1) Matz wants a compulsory warning here:

foo = 0
[1,2,3].each { |foo| # << HERE

}

Myself, and several others on this list, feel that this warning should be
optional. It’s not really necessary at all, unless you’re concerned about
making your scripts run on earlier versions of Ruby.

But I still hate shadowing, strong enough to raise warning.

(2) I asked for a warning (optional, with -w) if a local variable is
assigned but not used. Examples would be:

Nobu once made a patch for this. I didn’t merge it because it’s
little bit ugly in the current implementation. But I like the idea.
I will definitely add this check in the future release.

						matz.
···

In message “Re: Local variables & blocks” on 03/02/05, Brian Candler B.Candler@pobox.com writes:

>Myself, and several others on this list, feel that this warning should be
>optional. It's not really necessary at all, unless you're concerned about
>making your scripts run on earlier versions of Ruby.

But I still hate shadowing, strong enough to raise warning.

I think we'd all be reasonably happy with this warning as long as we
compromise on it being turned on with -w. You might hate shadowing, but many
of us happily re-use our little local variables like 'i' and 'j', which
works just fine as long as the values don't persist more than a few lines.

I think the point is, will this warning help you avoid shooting yourself in
the foot?

Under the current implementation of Ruby, because of 'action at a distance',
it would be useful to have a warning the other way round:

  i=0
  ...
  ... many lines
  ...
  [1,2,3].each { |i| # WARNING! i is bound to the global scope!
     ...
  }

But that's because you expected a local variable, and it might trip you up
if you get a method-wide one instead.

The converse is very unlikely to be a problem: i.e. you ask for and get a
block-local variable, and it just happens to be shadowing something you used
once and forgot about 10 screenfuls ago. In fact it's so unlikely to be a
problem that I would say don't warn at all, if it weren't for the backwards
compatibility issue.

To be honest, ruby's -w doesn't seem to catch very much anyway, although I
keep it on just as a habit from perl. This sort of warning may increase its
usefulness. But when running production scripts, under a web server for
example, the less garbage you can spew onto stderr the better.

>(2) I asked for a warning (optional, with -w) if a local variable is
>assigned but not used. Examples would be:

Nobu once made a patch for this. I didn't merge it because it's
little bit ugly in the current implementation. But I like the idea.
I will definitely add this check in the future release.

Thank you, that will be another boost to the usefulness of -w ...

Regards,

Brian.

···

On Wed, Feb 05, 2003 at 04:42:55AM +0900, Yukihiro Matsumoto wrote:

Hi,

···

At Wed, 5 Feb 2003 05:13:02 +0900, Brian Candler wrote:

Myself, and several others on this list, feel that this warning should be
optional. It’s not really necessary at all, unless you’re concerned about
making your scripts run on earlier versions of Ruby.

But I still hate shadowing, strong enough to raise warning.

I think we’d all be reasonably happy with this warning as long as we
compromise on it being turned on with -w. You might hate shadowing, but many
of us happily re-use our little local variables like ‘i’ and ‘j’, which
works just fine as long as the values don’t persist more than a few lines.

Although I agree that shadowing is one of the worst manners, it
might be too noisy when running a script expects current
behavior. What about warning when once shadowed variable is
re-used again?


Nobu Nakada

Hi,

···

In message “Re: Local variables & blocks” on 03/02/05, nobu.nokada@softhome.net nobu.nokada@softhome.net writes:

Although I agree that shadowing is one of the worst manners, it
might be too noisy when running a script expects current
behavior. What about warning when once shadowed variable is
re-used again?

Example?

						matz.
> > > But I still hate shadowing, strong enough to raise warning. > Although I agree that shadowing is one of the worst manners,

why such strong feelings?

i do this all the time and think it’s very clear :

n = ARGV.shift

n.times do |i|
Thread.new (i) do |i|

end
end

eg. i like shadowing when the shadow’d variable is the same_thing and
think this makes much more sense than :

n = ARGV.shift

n.times do |i|
Thread.new (i) do |j|

end
end

shadowing is not always bad IMHO.

-a

···

On Wed, 5 Feb 2003 nobu.nokada@softhome.net wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

Hi,

Although I agree that shadowing is one of the worst manners, it
might be too noisy when running a script expects current
behavior. What about warning when once shadowed variable is
re-used again?

Example?

foo = 0
[1,2,3].each do |foo| # (1)

end
puts foo # (2)

No warning at (1), probably unless -w, but warning at (2),
where `foo’ will be 0 under the new rule, whereas 3 under the
current rule.

If there is no line (2), that is `foo’ will never be used
again, it will be just discarded quietly regardless shadowed or
not.

···

At Wed, 5 Feb 2003 12:59:28 +0900, Yukihiro Matsumoto wrote:


Nobu Nakada