2008-09-30 9 views
23

In Ruby:Was ist "für" in Ruby

for i in A do 
    # some code 
end 

das gleiche wie:

A.each do |i| 
    # some code 
end 

for kein Kernel-Methode ist:

  • Was genau ist "for "in Ruby
  • Gibt es eine Möglichkeit, andere Keywords zu verwenden, um ähnliche Dinge zu tun ?

Etwas wie:

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

Mapping:

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

Antwort

45

Es ist fast Syntax Zucker. Ein Unterschied ist, dass, während for den Umfang des Codes um es verwenden würde, erstellt each einen separaten Bereich innerhalb seines Blocks. Vergleichen Sie die folgenden Schritte aus:

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

gegen

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

Wow, so subtil, und doch praktisch, wenn ich auf so etwas stoße. Vielen Dank! – sivabudh

+0

Tatsächlich löst das zweite Beispiel 'NameError: undefinierte lokale Variable oder Methode 'i' für main: Object' aus. Es liegt daran, dass du ein 'do' verpasst hast. –

+0

@JakubHampl Ich habe es behoben. Vielen Dank! –

14

for ist nur Syntax Zucker für die each Methode. Dies kann durch Ausführen dieses Codes zu sehen:

for i in 1 do 
end 

Diese im Fehler führt:

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

-1, weil es einen Unterschied zwischen den beiden ist, und sie sind nicht immer gleich. – user2398029

9

Für nur syntaktischer Zucker.

Von 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 

Rubin haben keine andere Schlüsselwörter für Listenkomprehensionen (wie die Summe Beispiel Sie oben hergestellt). for ist kein besonders beliebtes Schlüsselwort, und die Methodensyntax (arr.each {}) wird im Allgemeinen bevorzugt.