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

Asked

Viewed 165 times

10

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

Using the syntax for x in y:

> 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 to use one or the other?

1 answer

8


Are equivalent.

for a in b; code end is a syntax sugar for b.each {|a| code }, with the difference that the variable a 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 difference in performance in that the for was less efficient than the each, but this is of little significance from the 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));
}

It is worth noting that in ruby it is much more idiomatic and preferable to use the each in place of for, but this is more a matter of style than practice.

  • 1

    Nenhuma and a variável ainda está viva aqui, é a única diferença contradicts. :-)

  • A failed attempt to short Answer. I reformulated.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.