Range s sono oggetti matematici che precedono di molto la programmazione e gli array. Quello che puoi fare con un Range è controllare se un valore si trova entro un Range .
L'iterazione su un Range è non il caso d'uso principale; infatti, per un sacco di Range s, non è nemmeno possibile. Per esempio. per un Range di numeri reali, non puoi iterare su di esso perché non esiste il "prossimo numero reale": qualunque sia il numero reale che scegli come "il prossimo", ci sono ancora infiniti numeri reali tra la corrente e il "prossimo".
In Ruby, il protocollo Range è diviso in due: verifica e iterazione dei membri. Gli oggetti utilizzati come endpoint in Range s DEVONO implementare la porzione di controllo dei membri del protocollo e MAGGIO implementare ulteriormente la parte di iterazione del protocollo.
La parte di appartenenza del protocollo è semplice: sia l'oggetto di inizio che di fine devono rispondere al messaggio <=> (il metodo di confronto combinato standard che restituisce -1 , 0 , 1 o nil per oggetti che sono inferiori, uguali, maggiori o incomparabili). Per la parte di iterazione, anche l'oggetto start deve rispondere al messaggio succ (e l'oggetto restituito deve rispondere a succ e così via ...).
È perfettamente possibile in Ruby, ad esempio, costruire i seguenti Range di Rational numeri:
r = 1r..10r
Posso verificare l'appartenenza:
r.cover?(5r) #=> true
Ma non iterare:
r.to_a
# TypeError: can't iterate from Rational