for/in loop

H

Hal E. Fulton

I have been thinking about "for" and "in"
lately. Yeah, I should watch more TV.

Personally I rather like having this loop,
even though I rarely use it. Is that a
paradox? :)

I've heard it suggested that it is largely
pointless, and we should probably just use
'each' et al. instead.

But I don't see it ever going away, because
of its long history in Ruby and the many
lines of code that might potentially use it.

Matz, am I correct in guessing the for loop
will never go away?

Hal
 
P

Paul Brannan

I've heard it suggested that it is largely
pointless, and we should probably just use
'each' et al. instead.

It's definitely not pointless:

for i in [1, 2, 3]
x = i
end
p x #=> 3

[1, 2, 3].each do
y = i
end
p y #=> test.rb:9: undefined local variable or method `y' for #<Object:0x40289ce0> (NameError)

Paul
 
Y

Yukihiro Matsumoto

Hi,

In message "for/in loop"

|Matz, am I correct in guessing the for loop
|will never go away?

It won't. It has long history way back in my university theses, from
a language named 'classic'. 14 years since then. Time flies.

matz.
 
D

Dan Doel

Paul said:
It's definitely not pointless:

for i in [1, 2, 3]
x = i
end
p x #=> 3

[1, 2, 3].each do
y = i
end
p y #=> test.rb:9: undefined local variable or method `y' for #<Object:0x40289ce0> (NameError)

To do the same using #each, you'd need:

y = nil
[1, 2, 3].each do|i|
y = i
end

Which is uglier, I admit, but still possible.

- Dan
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: for/in loop"

|It's definitely not pointless:
|
| for i in [1, 2, 3]
| x = i
| end
| p x #=> 3
|
| [1, 2, 3].each do
| y = i
| end
| p y #=> test.rb:9: undefined local variable or method `y' for #<Object:0x40289ce0> (NameError)

Yes, but it would work, when new scoping rule is introduced.

matz.
 
O

Olivier Nenert

hi Hal,
I think kurt was asking "which one of the two scenarios would be fixed by a
new scoping rule ?"
not "what do you mean by it would work ?"
It's an exelent question I think, when the new scoping rule is introduced,
either y will be visible outside the each scope,
or the x will stop being visible ouside the for loop,
I wonder too, surely Matz knows so well what he talks about it was obvious
to him, but it isn't to me
(and Kurt I guess) :)

Cheers,
Olivier.
(thanx for your posts btw, I'm just starting to read about ruby
and found your posts to be the most helpful so far)
----- Original Message -----
From: "Kurt M. Dresner" <[email protected]>
To: "ruby-talk ML" <[email protected]>
Sent: Wednesday, August 20, 2003 1:07 PM
Subject: Re: for/in loop

What do you mean by it would work? The first one will raise a
NameError, or the second one will output 3 ?

I think it's a minor problem with Matz's English. I believe he
means "it will work when the new scoping rule is introduced" or
"it would work, if the new scoping rule were already in place."

Hal

-Kurt

Hi,

In message "Re: for/in loop"

|It's definitely not pointless:
|
| for i in [1, 2, 3]
| x = i
| end
| p x #=> 3
|
| [1, 2, 3].each do
| y = i
| end
| p y #=> test.rb:9: undefined local variable or method `y' for
# said:
Yes, but it would work, when new scoping rule is introduced.

matz.

======= End of Original Message =======<
 
Y

Yukihiro Matsumoto

Hi,

Sorry for confusion.

In message "Re: for/in loop"

|I think kurt was asking "which one of the two scenarios would be fixed by a
|new scoping rule ?"

First of all, I shouldn't have write "would". I meant "will".

Then, the answer to Olivier's (and Kurt's) question is: the latter
(i.e. second one will output 3).

The variables-first-appear-in-a-block-are-local-to-the-block rule will
be obsoleted. Local variables will be local to the block only when
they appear in the block parameter list.

matz.
 
M

Mauricio Fernández

The variables-first-appear-in-a-block-are-local-to-the-block rule will
be obsoleted. Local variables will be local to the block only when
they appear in the block parameter list.

Are you sure you'll drop ':='?

local |bla| do

end

is very verbose and is just a declaration (which you wanted to avoid) under cover.

:= would be an interesting experiment, one that could easily be undone
by a small filter were it to be abandoned later.

--
_ _
| |__ __ _| |_ ___ _ __ ___ __ _ _ __
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

'Ooohh.. "FreeBSD is faster over loopback, when compared to Linux
over the wire". Film at 11.'
-- Linus Torvalds
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: for/in loop"

|Are you sure you'll drop ':='?

Not a final decision. But I feel like := can be abused (i.e. from my
point of view that block local variables are evil) too easily.

matz.
 
P

Paul Brannan

Do you have an explanation posted somewhere of why you feel block-local
variables are evil? It seems cleaner to me to have variables go
away at the end of the block when I don't need them anymore, than
to have them hanging around and taking up memory until the whole method
exits.

If this is really a concern for you, it should probably be a sign that
the method is too long and needs to be broken down into many separate
methods, each with a distinct purpose.

Paul
 
B

Brett H. Williams

If this is really a concern for you, it should probably be a sign that
the method is too long and needs to be broken down into many separate
methods, each with a distinct purpose.

The pitfall of block local variables (they way Ruby works now)...


There seems to be nothing wrong with:

def action(foo)
foo.each do |x|
some_str = transform(x.some_attr.strip)
puts "transformed some_attr for #{x}: #{some_str}"
end
# ...
end

It's nice to know that some_str is not polluting the variable namespace of
the action() method. In practice it probably doesn't matter (if you
assumed it was block local and used it elsewhere later in action(), it'd be
reassigned anyhow). If it was used prior to the block, then it isn't block
local under the current scheme.

I guess it's impossible to have a situation where changing Ruby to get rid
of block local variables would cause a problem with existing code.

As far as why the current implicit lexical scoping scheme could be
considered evil, consider this:

def action(foo)
some_str = some_method()
foo.each { |x| some_str = ... } # I meant for some_str to be block local
some_other_method(some_str) # oops! modified in the block!
end

I _think_ this why people say they are evil--because knowing that block
local variables spring into existence (implicit scoping) can lead you to
believe you are protected when sometimes you aren't. A couple of times
I've accidentally done this (usually in the presence of cut and paste), and
it can be a subtle bug to deal with.

That's why breaking a method up would lessen the chances of this occurring,
as you'd be less likely to see you'd used a variable in a block which
already had scope in the method.

Does that help? Or maybe I'm even missing something else evil? Is there
something evil in general about block locals, even if they _aren't_
implicitly scoped? Because I think something that is explicitly stated to
be block local obviously doesn't suffer from the above pitfall, and I can't
see the problem with that.

As to whether it's necessary though...

Just my $.02
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,109
Messages
2,570,671
Members
47,262
Latest member
EffiePju4

Latest Threads

Top