回答:
これが唯一の違いです。
各:
irb> [1,2,3].each { |x| }
=> [1, 2, 3]
irb> x
NameError: undefined local variable or method `x' for main:Object
from (irb):2
from :0
ために:
irb> for x in [1,2,3]; end
=> [1, 2, 3]
irb> x
=> 3
for
ループを使用すると、ブロックが完了した後もイテレーター変数は引き続き有効です。でeach
ループが開始する前に、それがすでにローカル変数として定義されていない限り、ループ、それは、ありません。
それ以外for
は、each
メソッドの構文糖衣です。
とき@collection
でnil
両方のループは、例外をスロー:
例外:main:Objectの未定義のローカル変数またはメソッド `@collection '
x
残る理由は、(一般的に言えば)キーワードでは新しいスコープが作成されないためです。if、unless、begin、for、whileなどはすべて、現在のスコープで機能します。ただし、ブロックを受け入れます。ブロックは常に現在のスコープの上に独自のスコープを追加します。ブロックで新しい変数を宣言する(つまり、新しいスコープ)ことは、その追加のスコープが利用できないため、ブロックの外部からアクセスできないことを意味します。#each
もう1つ…
number = ["one", "two", "three"]
=> ["one", "two", "three"]
loop1 = []
loop2 = []
number.each do |c|
loop1 << Proc.new { puts c }
end
=> ["one", "two", "three"]
for c in number
loop2 << Proc.new { puts c }
end
=> ["one", "two", "three"]
loop1[1].call
two
=> nil
loop2[1].call
three
=> nil
ソース:http : //paulphilippov.com/articles/enumerable-each-vs-for-loops-in-ruby
より明確にするために:http : //www.ruby-forum.com/topic/179264#784884
違いはないようですが、下でfor
使いeach
ます。
$ irb
>> for x in nil
>> puts x
>> end
NoMethodError: undefined method `each' for nil:NilClass
from (irb):1
>> nil.each {|x| puts x}
NoMethodError: undefined method `each' for nil:NilClass
from (irb):4
ベヤードが言うように、それぞれはより慣用的です。それはあなたからより多くを隠し、特別な言語機能を必要としません。 Telemachusのコメントごと
for .. in ..
イテレータをループのスコープ外に設定するため、
for a in [1,2]
puts a
end
a
ループの終了後に定義された葉。each
ないところ。これはeach
、temp変数の有効期間が短いため、を使用する理由の1つです。
for
は使用しませんeach
。他の回答を参照してください。
絶対に使用for
しないでください。ほとんど追跡できないバグが発生する可能性があります。
だまされてはいけません、これは慣用的なコードやスタイルの問題についてではありません。Rubyのの実装にfor
は重大な欠陥があるため、使用しないでください。
これはfor
バグを導入する例です、
class Library
def initialize
@ary = []
end
def method_with_block(&block)
@ary << block
end
def method_that_uses_these_blocks
@ary.map(&:call)
end
end
lib = Library.new
for n in %w{foo bar quz}
lib.method_with_block { n }
end
puts lib.method_that_uses_these_blocks
プリント
quz
quz
quz
%w{foo bar quz}.each { |n| ... }
プリントの使用
foo
bar
quz
どうして?
内for
ループ変数がn
一度だけ、次いで一つの定義は、すべての反復のための使用であると定義されます。したがって、各ブロックは、ループが終了n
するまでに値を持つものを参照しquz
ます。バグ!
each
新鮮な変数がループn
反復ごとに定義され、変数上記例えばn
3つの別々の回に定義されています。したがって、各ブロックはn
正しい値で個別を参照します。
私の知る限り、言語内の制御構造の代わりにブロックを使用する方が慣用的です。
Rubyのforループについて特定の点を述べたいだけです。それは他の言語に似た構成要素のように見えるかもしれませんが、実際には、Rubyの他のすべてのループ構成要素と同様の式です。実際、for inは、各イテレータと同じようにEnumerableオブジェクトを処理します。
forに渡されるコレクションは、各反復子メソッドを持つ任意のオブジェクトにすることができます。配列とハッシュはそれぞれのメソッドを定義し、他の多くのRubyオブジェクトもそうです。for / inループは、指定されたオブジェクトのeachメソッドを呼び出します。そのイテレーターが値を生成すると、forループは各値(または各値のセット)を指定された変数(または変数)に割り当て、コードを本体で実行します。
これはばかげた例ですが、forループが、各反復子が行うのと同じように、eachメソッドを持つANYオブジェクトで機能する点を示しています。
class Apple
TYPES = %w(red green yellow)
def each
yield TYPES.pop until TYPES.empty?
end
end
a = Apple.new
for i in a do
puts i
end
yellow
green
red
=> nil
そして、それぞれのイテレータ:
a = Apple.new
a.each do |i|
puts i
end
yellow
green
red
=> nil
ご覧のように、どちらもブロックに値を返すeachメソッドに応答しています。ここで述べたように、forループではなく、各反復子を使用することが明らかに望ましいです。私はfor inループに魔法のようなものは何もないという点に帰りたかっただけです。これは、コレクションの各メソッドを呼び出し、それをコードのブロックに渡す式です。したがって、これを使用する必要があるのは非常にまれなケースです。各反復子をほぼ常に使用します(ブロックスコープの利点が追加されます)。