2010-07-09 5 views
6

Das Iterieren eines Blocks in Ruby ist einfach genug - es endet sauber und geht weiter zum Rest des Codes.Ruby Enumerator - Warum mit Ausnahme abschließen?

Das Iterieren mit einem Enumerator hingegen ist etwas verwirrender. Wenn Sie Folgendes aufrufen: jeweils ohne einen Block, wird stattdessen ein Enumerator zurückgegeben. : next kann dann auf dem Enumerator aufgerufen werden, um den nächsten iterativen Wert zu erhalten.

Und dann der ungerade Teil - wenn die Iteration abgeschlossen ist, statt der Enumerator Nil zurückgibt, wird eine Ausnahme ausgelöst: "Iteration am Ende erreicht". Das Ergebnis ist, dass es nicht einmal einen Wert zurückgibt.

Zum Beispiel:

test = [ 'test_value' ] 
enumerator = test.each 
enumerator.next 
>> "test_value" 
enumerator.next 
>> StopIteration: iteration reached at end 

Ist der Grund dafür einfach so, dass Null-Werte von dem Enumerator zurückgegeben werden können? Die Antwort kommt mir nur vor, wenn ich dies poste (also werde ich es noch posten), aber es scheint, als ob es der Fall sein muss.

Wenn das so ist, ist dies ein typischer Weg, um solche Probleme zu behandeln? Es ist seltsam, eine Ausnahme zu verwenden, um Code zu verarbeiten, der im Wesentlichen wie erwartet funktioniert.

Antwort

6

Du hast Recht, dass der Grund dafür ist, dass nil vom Enumerator als gültiger Wert zurückgegeben werden kann. Um Ihre Frage zu beantworten, ob dies typisch ist, behandelt Python sie auf dieselbe Weise mit einer Ausnahme, die auch StopIteration genannt wird.

>>> my_list = [1,2,3] 
>>> i = iter(my_list) 
>>> i.next() 
1 
>>> i.next() 
2 
>>> i.next() 
3 
>>> i.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

Natürlich meiste Zeit next wird nicht direkt aufgerufen (each oder eine for Schleife stattdessen verwendet werden), so dass diese zugrunde liegende Mechanismus oft nicht ausgesetzt ist.

+1

OCaml geht sogar noch weiter - das mehr oder weniger äquivalente von Rubys 'hash [key]' ('List.assoc key hash') löst eine Exception (' Not_found') aus, wenn der Schlüssel nicht dargestellt wird. Es ist eigentlich ziemlich logisch - das "normale" Ding, das man erwartet, wenn man ': next' aufruft, ist der nächste Wert. * Nicht * den nächsten Wert zu bekommen ist eindeutig eine Ausnahmesituation. – Amadan

+1

@Amadan: 'hash.fetch (key)' wird einen 'KeyError' auslösen, wenn der Schlüssel nicht gefunden wird. –

+0

Interessantes Argument Amadan - ich kaufe es. – Asher

3

Ja, Nil ist immer noch ein Ergebnis, das anders ist, als keinen Wert zurückzugeben. Es ist im Prinzip das Gleiche wie der Versuch, auf eine Variable oder einen Speicherort im Speicher zuzugreifen, der nicht vorhanden ist. Deshalb möchten Sie eine Ausnahme, anstatt eine Null zurückgeben. Klingt, als ob du das herausgefunden hättest:

Verwandte Themen