2008-09-30 7 views
23

Dans Ruby:Qu'est-ce que "pour" Ruby

for i in A do 
    # some code 
end 

est le même que:

A.each do |i| 
    # some code 
end 

for est pas une méthode du noyau:

  • Qu'est-ce que «for exactement "in ruby ​​
  • Existe-t-il un moyen d'utiliser d'autres mots-clés pour faire des choses similaires? ?

Quelque chose comme:

total = sum i in I {x[i]} 

mapping à:

total = I.sum {|i] x[i]} 

Répondre

45

C'est presque du sucre de syntaxe. Une différence est que, tandis que for utiliserait la portée du code qui l'entoure, each crée une portée distincte dans son bloc. Comparer les suivantes:

for i in (1..3) 
    x = i 
end 
p x # => 3 

contre

(1..3).each do |i| 
    x = i 
end 
p x # => undefined local variable or method `x' for main:Object 
+0

Wow, si subtile, mais deviendra utile lorsque je rencontre quelque chose comme ça. Merci! – sivabudh

+0

En fait votre second exemple lance 'NameError: variable locale non définie ou méthode 'i' pour main: Object'. C'est parce qu'il te manque un 'do'. –

+0

@JakubHampl Je l'ai réparé. Merci! –

14

for est le sucre juste syntaxe pour la méthode each. Cela peut être vu en exécutant ce code:

for i in 1 do 
end 

Il en résulte l'erreur:

NoMethodError: undefined method `each' for 1:Fixnum 
+3

-1 parce qu'il ya une différence entre les deux, et ils ne sont pas toujours équivalentes. – user2398029

9

est juste pour le sucre syntaxique.

De the pickaxe:

For ... In

Earlier we said that the only built-in Ruby looping primitives were while and until. What's this ``for'' thing, then? Well, for is almost a lump of syntactic sugar. When you write

for aSong in songList 
    aSong.play 
end 

Ruby translates it into something like:

songList.each do |aSong| 
    aSong.play 
end 

The only difference between the for loop and the each form is the scope of local variables that are defined in the body. This is discussed on page 87.

You can use for to iterate over any object that responds to the method each, such as an Array or a Range.

for i in ['fee', 'fi', 'fo', 'fum'] 
    print i, " " 
end 
for i in 1..3 
    print i, " " 
end 
for i in File.open("ordinal").find_all { |l| l =~ /d$/} 
    print i.chomp, " " 
end 

produces:

fee fi fo fum 1 2 3 second third 

As long as your class defines a sensible each method, you can use a for loop to traverse it.

class Periods 
    def each 
    yield "Classical" 
    yield "Jazz" 
    yield "Rock" 
    end 
end 


periods = Periods.new 
for genre in periods 
    print genre, " " 
end 

produces:

Classical Jazz Rock 

Ruby n'a pas d'autres mots-clés pour compréhensions de liste (comme l'exemple de la somme que vous avez fait ci-dessus). for n'est pas un mot-clé terriblement populaire, et la syntaxe de la méthode (arr.each {}) est généralement préférée.