2010-05-28 5 views
14

Ich versuche, ein Projekt Euler Problem mit Ruby zu lösen, habe ich 4 verschiedene Schleifenmethoden, die for-Schleife, Zeiten, Bereich und upto-Methode, aber die Zeiten-Methode produziert nur die erwartete Antwort, während die for-Schleife, Bereich und upto-Methode nicht. Ich gehe davon aus, dass sie ungefähr gleich sind, aber ich habe herausgefunden, dass es nicht so ist. Kann jemand bitte die Unterschiede zwischen diesen Methoden erklären?Looping Unterschiede in Ruby mit Range vs. Zeiten

Hier ist die Schleifenstruktur I

# for-loop method 
for n in 0..1 
    puts n 
end 

0 
1 
=> 0..1 

# times method 
2.times do |n| 
    puts n 
end 

0 
1 
=> 2 

# range method 
(0..1).each do |n| 
    puts n 
end 

0 
1 
=> 0..1 

# upto method 
0.upto(1) do |n| 
    puts n 
end 

0 
1 
=> 0 

Antwort

6

Diese Information verwendet wird, kann leicht durch Überprüfen der Dokumentation.

Array#each hat eine Signatur von array.each {|item| block } → array, so können wir sehen, dass der Rückgabewert von foo.each { ... }foo ist.

Ebenso hat Int#upto eine Signatur von int.upto(limit) {|i| block } => int, so dass x.upto(y) { ... } immer x zurückgibt.

Dann können wir auch sehen, dass 2.times { ... } 2 wegen der Unterschrift Integer#times zurückgeben wird.

Ich habe Probleme die richtige Dokumentation zu finden, aber for x in y... wird zu y.each do |x| ... übersetzt, so dass deshalb Ihre for-Schleife in die gleichen wie Ihre .each Schleife zurück.

Wie auch immer, abhängig von der Rückgabe Werte dieser Schleifenkonstrukte ist ... ein seltsamer Ansatz. Ich glaube nicht, dass dies im idiomatischen Ruby-Code viel passiert (überhaupt?).

+0

Es klingt für mich nicht so, als würde er nach dem Rückgabewert fragen. – sepp2k

+0

@ sepp2k: Ich sah, dass die * Ausgabe * jeder Anweisung '0 1' war, während die Rückgabewerte, wie durch '=>' angegeben, 3 verschiedene Werte hatten. Die Frage hätte auf jeden Fall klarer formuliert werden können. –

+0

Hm, du hast wahrscheinlich recht. – sepp2k

3

Wenn ich Sie richtig verstanden habe, fragen Sie, warum n.times die einzige Methode ist, die iteriert, aber nicht einschließlich n. In diesem Fall:

Für Bereiche ist es einfach: x..y definiert einen Bereich von x bis y inklusive und x...y definiert einen Bereich von x bis y exklusiv. Wenn Sie also das gleiche Verhalten wie Zeiten verwenden möchten, verwenden Sie 0...n.

Für x.upto(y) gibt es nur eine Version, die bis einschließlich y iteriert. Dies ist einfach so, wie bis zu dem Punkt definiert und dokumentiert ist, um zu funktionieren.

Es ist auch ziemlich klar, warum n.times n nicht enthält: wenn es von 0 bis n (einschließlich) iterierte, würde es mal ergeben. Aber da die Methode n.times heißt, sollte sie eindeutig nur n-mal ergeben.