Last Updated: February 25, 2016
· tony612

For is almost a lump of syntactic sugar in ruby!

Do you know for is almost a lump of syntactic sugar in ruby?
Yes, the for in ruby is not like that in others.
When you write
for i in collection p i end
Ruby translates it into sth like:
collection.each do |i| p i end
But, the difference is that each invokes the block of code repeatly, while for is just a language construct.

So if the variable has existed before the block, that in the block is the same with the outside one. But if the variable appears only inside the block, it's local to the block, it can't be accessed anywhere outside the block.

There is a good example to explain it: https://gist.github.com/4109520

11 Responses
Add your response


Cool. I never liked for anyway; happy to know it doesn't really exists :)

over 1 year ago ·

Ruby has a for statement?! O.o And it's just a sugar over #each? Ah, useless~

over 1 year ago ·

For would be more useful if it was sugar on map and flatMap like in Scala. Anyway, good to know. Thanks.

over 1 year ago ·

No, it isn't.

foo.each do |blah|

creates a new lexical scope for the block,

for i in foo

Does not. If you don't know what you're talking about, please don't preach. You're misleading people.

over 1 year ago ·

@richoh . I don't want to mislead people. I just read the Loops part in the book <Programming Ruby>(1.9,3rd) at Page 162. It said that the only built-in Ruby looping primitives were while and until, foris almost a lump of syntactic sugar. And you can use for loop only if your class define a each method

over 1 year ago ·

Yeah, you read it wrong.

For doesn't create any local scope. Example here: https://gist.github.com/4109520

over 1 year ago ·

@richoh I think I have known what your meaning is. I forget to mention the different between them. Thank your very much. I'll fix it ~

over 1 year ago ·

I don't get it. Have you updated it? This is still blatantly wrong.

over 1 year ago ·

@richoh It's ok now?

over 1 year ago ·

Not really. I think you're trying to explain something you don't really understand. Which is fine.. but you probably shouldn't be teaching your interpretation as fact.

When you invoke each you're defining a block, which is a binding complete with it's own local scope and then passing that into the each method, which calls your block once for each value in the set.

block = Proc.new do |v|
puts v

[1, 2, 3].each(&block)
[4, 5, 6].each(&block)

The block is an entirely seperate entity.The for loop is a language construct.

over 1 year ago ·

@richoh thank you again. I just updated it. Is there something wrong?

over 1 year ago ·