How can I show that the Ruby `for` loop is in fact implemented using the `each` method?

前端 未结 3 778
栀梦
栀梦 2021-01-19 00:32

In the book Eloquent Ruby (page 21, first edition, sixth printing), the author (Russ Olsen) advocates using the each method instead of

3条回答
  •  没有蜡笔的小新
    2021-01-19 01:01

    The semantics of the for expression are defined in the ISO Ruby Language Specification like this:

    §11.4.1.2.3 The for expression

    Syntax

    • for-expression for for-variable in expression do-clause end
    • for-variable left-hand-side | multiple-left-hand-side

    The expression of a for-expression shall not be a jump-expression.

    Semantics

    A for-expression is evaluated as follows:

    1. Evaluate the expression. Let O be the resulting value.
    2. Let E be the primary-method-invocation of the form primary-expression [no line-terminator here].each do | block-formal-argument-list | block-body end, where the value of the primary-expression is O,the block-formal-argument-list is the for-variable, the block-body is the compound-statement of the do-clause.

      Evaluate E, but skip Step c of §11.2.2.

    3. The value of the for-expression is the resulting value of the invocation.

    Okay, so basically this means that

    for for_variable in expression
      do_clause
    end
    

    is evaluated the same as

    O = expression
    O.each do |for_variable|
      do_clause
    end
    

    Aha! But we forgot something! There's this ominous "skip Step c of §11.2.2." thing! So, what does Step c of §11.2.2. say?

    • Push an empty set of local variable bindings onto ⟦local-variable-bindings⟧.

    Note that Step b

    • Set the execution context to Eb.

    is not skipped.

    So, a for loop gets its own execution context, which starts out as a copy of the current execution context, but it does not get its own set of local variable bindings. IOW: it gets its own dynamic execution context, but not its own lexical scope.

提交回复
热议问题