2010-07-09 12 views
6

L'iterazione di un blocco in Ruby è abbastanza semplice: termina in modo pulito e procede al resto del codice.Ruby Enumerator - Perché terminare con l'eccezione?

L'iterazione con un enumeratore, d'altra parte, è un po 'più confusa. Se si chiama: ciascuno senza un blocco, viene invece restituito un enumeratore. : successivo può quindi essere chiamato sull'Enumeratore per ottenere ogni successivo valore iterativo.

E poi la parte dispari- quando l'iterazione è completa, anziché l'enumeratore che restituisce nil, genera un'eccezione: "iterazione raggiunta alla fine". Il risultato è che non restituisce nemmeno un valore.

Per esempio:

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

è la ragione di questo semplicemente in modo che i valori nulli possono essere restituiti dal enumeratore? La risposta mi viene in mente solo quando la postò (quindi lo posterò ancora), ma sembra che debba essere il caso.

Se è così, è questo un modo tipico di gestire tali problemi? Sembra strano usare un'eccezione per gestire il codice che si comporta essenzialmente come previsto.

risposta

6

Hai ragione, il motivo è che nil può essere restituito come un valore valido dall'Enumeratore. Per rispondere alla tua domanda se questo è tipico, Python lo gestisce allo stesso modo usando un'eccezione chiamata anche StopIteration.

>>> 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 

Naturalmente, la maggior parte del tempo next non è chiamato direttamente (each o un for ciclo viene utilizzato invece) così questo meccanismo sottostante non è esposto spesso.

+1

OCaml va anche oltre - più o meno equivalente di 'hash di Ruby [tasto]' ('List.assoc hash' chiave) solleva un'eccezione (' Not_found') se la chiave non è rappresentato. In realtà è abbastanza logico: la cosa "normale" che ti aspetti quando chiami ": next" è ottenere il valore successivo. * Non * ottenere il valore successivo è chiaramente una situazione eccezionale. – Amadan

+1

@Amadan: 'hash.fetch (chiave)' genererà un 'KeyError' se la chiave non viene trovata. –

+0

Argomento interessante Amadan: lo compro. – Asher

3

Sì, nil è ancora un risultato, che è diverso dal non avere un valore da restituire. È praticamente lo stesso che provare ad accedere a una variabile oa una posizione in memoria che non c'è. Questo è il motivo per cui vuoi un'eccezione piuttosto che restituire un nulla. Sembra che tu l'abbia capito :-)

Problemi correlati