5

重複の可能性:
Rubyのvsそれぞれ

次のような配列があるとしましょう

sites = %w[stackoverflow stackexchange serverfault]

の違いは何ですか

for x in sites do
  puts x
end

sites.each do |x|
  puts x
end

彼らは私にはまったく同じことをしているように見え、forループの構文は私にはより明確です。違いはありますか?どのような状況でこれは大したことになるでしょうか?

4

4 に答える 4

27

スコーピングに関しては微妙な違いがありますが、Rubyの重要な側面のいくつかが明らかになるので、よく理解することをお勧めします。

forは構文構造であり、にいくらか似ていifます。forブロックで定義するものは何でも、その後forも定義されたままになります。

sites = %w[stackoverflow stackexchange serverfault]
#=> ["stackoverflow", "stackexchange", "serverfault"]

for x in sites do
  puts x
end
stackoverflow
stackexchange
serverfault
#=> ["stackoverflow", "stackexchange", "serverfault"]
x
#=> "serverfault"

一方、eachはブロックを受け取るメソッドです。ブロックは新しい字句スコープを導入するため、ブロックに導入する変数は、メソッドの終了後には存在しません。

sites.each do |y|
  puts y
end
stackoverflow
stackexchange
serverfault
#=> ["stackoverflow", "stackexchange", "serverfault"]
y
NameError: undefined local variable or method `y' for #<Object:0x855f28 @hhh="hello">
    from (irb):9
    from /usr/bin/irb:12:in `<main>'

列挙型をトラバースするためにRubyでfor使用するのは慣用的であるため、完全に忘れることをお勧めします。eachまた、副作用の可能性を減らすことにより、関数型プログラミングのパラダイムをよりよく認識します。

于 2011-04-15T13:09:14.923 に答える
8

sites.eachxブロック内のスコープ。ブロック外で宣言された場合forは再利用されます。xしたがって、一般的には、を使用するeachことをお勧めします。これにより、大量のコードに対する副作用が最小限に抑えられます。

于 2011-04-15T13:00:26.960 に答える
4

CBZの答えは正しいですが、1.8.Xと1.9.Xの間で動作に違いがあるため、不完全です。

1.9.2 IRB:

ruby-1.9.2-p180 :001 > x = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :002 > y = ["a","b"]
 => ["a", "b"] 
ruby-1.9.2-p180 :003 > x.each do |y|
ruby-1.9.2-p180 :004 >     p y
ruby-1.9.2-p180 :005?>   end
1
2
3
4
5
 => [1, 2, 3, 4, 5] 
ruby-1.9.2-p180 :006 > y
 => ["a", "b"] 

1.8.7 IRB:

ree-1.8.7-2011.03 :001 > x = [1,2,3,4,5]
 => [1, 2, 3, 4, 5] 
ree-1.8.7-2011.03 :002 > y = ["a","b"]
 => ["a", "b"] 
ree-1.8.7-2011.03 :003 > x.each do |y|
ree-1.8.7-2011.03 :004 >     p y
ree-1.8.7-2011.03 :005?>   end
1
2
3
4
5
 => [1, 2, 3, 4, 5] 
ree-1.8.7-2011.03 :006 > y
 => 5 
于 2011-04-15T13:10:39.050 に答える
-1

CBZの答えは正しいです。これを説明するには、次の例を参照してください。

ruby-1.9.2-p180 :001 > a = %w{ blah lah kah }
 => ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :002 > x = 1
 => 1 
ruby-1.9.2-p180 :003 > for x in a do
ruby-1.9.2-p180 :004 >     puts x
ruby-1.9.2-p180 :005?>   end
blah
lah
kah
 => ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :006 > x
 => "kah" 
ruby-1.9.2-p180 :007 > x=1
 => 1 
ruby-1.9.2-p180 :008 > a.each do |x|
ruby-1.9.2-p180 :009 >     puts x
ruby-1.9.2-p180 :010?>   end
blah
lah
kah
 => ["blah", "lah", "kah"] 
ruby-1.9.2-p180 :011 > x
 => 1 
于 2011-04-15T13:04:37.487 に答える