Gli intervalli rappresentano un intervallo compreso tra due valori.
I tipi più comuni che supportano gli intervalli sono Integer e String.
Si possono usare per molte cose: creare rapidamente una collezione, estrarre sottostringhe, verificare se un valore è compreso in un intervallo e iterare.
Si creano usando l'operatore di intervallo .. o ... (rispettivamente inclusivo ed esclusivo).
1..5 # => 1..5
1...5 # => 1...5
(1..5).to_a # => [1, 2, 3, 4, 5]
(1...5).to_a # => [1, 2, 3, 4]
Il motivo per cui esistono due operatori di intervallo è permettere di creare intervalli che includono o escludono il valore finale. Questo può essere utile, per esempio, quando si lavora con indici che partono da zero.
Gli intervalli si possono anche creare usando l'inizializzatore di Range.
Range.new(1, 5) # A range containing 1, 2, 3, 4, 5
Quando crei un intervallo in Ruby con gli operatori .. o ... e vuoi chiamare un metodo su quell'intervallo, devi racchiuderlo tra parentesi.
Il motivo è che altrimenti il metodo verrebbe chiamato sul secondo argomento dell'operatore di intervallo.
(1..5).sum # => 15
1..5.sum # => Error: undefined method `sum' for 5:Integer (NoMethodError)
Quando vuoi estrarre una sottostringa da una stringa, puoi usare l'operatore di intervallo. Ti basta creare un intervallo con l'indice iniziale e quello finale della sottostringa.
"Hello World"[0..4] # => "Hello"
"Hello World"[6..10] # => "World"
Puoi anche usare indici negativi per ottenere la sottostringa dalla fine della stringa.
"Hello World"[-5..-1] # => "World"
"Hello World"[6..-4] # => "Wo"
Gli intervalli hanno una serie di metodi con cui lavorare. Per esempio, questi metodi permettono di ottenere la somma di tutti i valori dell'intervallo o di verificare se l'intervallo include un valore.
| Method | Description | Example |
|---|---|---|
sum |
Restituisce la somma di tutti i valori dell'intervallo | (1..5).sum # => 15 |
size |
Restituisce la dimensione dell'intervallo | (1..5).size # => 5 |
include? |
Restituisce true se l'intervallo include il valore indicato, altrimenti false
|
(1..5).include?(3) # => true |
Un intervallo può essere senza fine o senza inizio.
In un intervallo senza fine o senza inizio il valore iniziale o quello finale è nil, ma quando definisci l'intervallo puoi omettere nil.
Usare intervalli senza inizio e senza fine è utile quando vuoi, per esempio, estrarre una sottostringa dall'inizio o fino alla fine.
"Hello World"[0..] # => "Hello World"
"Hello World"[4..] # => "o World"
"Hello World"[..5] # => "Hello "
Se non lo si usa su una collezione, l'intervallo senza fine può dare origine a una sequenza infinita, se non lo si usa con cautela.
Anche le stringhe si possono usare negli intervalli e permettono di ottenere un intervallo di stringhe comprese tra due stringhe. Il suo comportamento può essere un po' inaspettato con certe stringhe, quindi usalo con cautela.
"aa".."az".to_a # => ["aa", "ab", "ac", ..., "az"]
Ruby ti permette di usare oggetti personalizzati negli intervalli. Il requisito è che l'oggetto implementi quanto segue:
Comparable
succ
<=>
Questi metodi fanno sì che l'intervallo possa iterare sull'oggetto e confrontare tra loro gli oggetti che contiene.
class Foo
include Comparable
attr_reader :value
def initialize(value)
@value = value
end
def succ
Foo.new(value + 1)
end
def <=>(other)
value <=> other.value
end
end
(Foo.new(1)..Foo.new(5))
# => #<Foo:0x7f3552bebe70 @value=1>, #<Foo:0x7f3552bebe50 @value=2>, #<Foo:0x7f3552bebe40 @value=3>, #<Foo:0x7f3552bebe30 @value=4>, #<Foo:0x7f3552bebe20 @value=5>