What is the difference between 'for x in y' and 'Enumerable # each'?

9

We can iterate an Array / list in ruby in two ways:

Using the for x in y syntax:

> for x in [1,2,3] do
>     puts x
>   end
1
2
3
 => [1, 2, 3] 

Using the method .each

> [1,2,3].each do |x|
>     puts x
>   end
1
2
3
 => [1, 2, 3] 

What's the difference between them, and when should I use one or the other?

    
asked by anonymous 17.02.2014 / 23:19

1 answer

7

They are equivalent.

for a in b; code end is a syntax sugar for b.each {|a| code } , with the difference that the a variable does not have its scope limited to the block. A simple proof for this is as follows:

class A
  def each(&block)
    block.call(1)
    block.call(2)
    block.call(42)
  end
end

for x in A.new
  p x
end
# mostra 1, 2 e 42

p x   # mostra 42
      # a variável ainda está viva aqui, é a única diferença

There was a performance difference where for was less efficient than each , but that's not significant since Ruby 2.0 .

As a reference, part of compile.c :

// Ao encontrar um "for"
if (nd_type(node) == NODE_FOR) {
    COMPILE(ret, "iter caller (for)", node->nd_iter);

    // Crie um bloco para ele
    iseq->compile_data->current_block =
    NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq),
              ISEQ_TYPE_BLOCK, line);

    // Crie uma invocação ao método "each" passando o bloco
    ADD_SEND_R(ret, line, ID2SYM(idEach), INT2FIX(0),
           iseq->compile_data->current_block, INT2FIX(0));
}

Note that ruby is much more idiomatic and preferable to use each instead of for , but this is more a matter of style than practice.

    
17.02.2014 / 23:24