# Catene di anelli

In aggiunta ai costrutti tipo `range` e `spread`, un altro modo di creare nuovi anelli è manipolando anelli esistenti.

## Comandi di concatenazione

Per capirci di più, prendiamo un semplice anello:

    (ring 10, 20, 30, 40, 50)

Se volessimo riprodurlo al contrario? Beh, utilizzeremo il comando `.reverse` per girare quell’anello:

    (ring 10, 20, 30, 40, 50).reverse  #=> (ring 50, 40, 30, 20, 10)

Ora, se volessimo solo i primi tre valori dell’anello?

    (ring 10, 20, 30, 40, 50).take(3)  #=> (ring 10, 20, 30)

Infine, se volessimo dei valori casuali?

    (ring 10, 20, 30, 40, 50).shuffle  #=> (ring 40, 30, 10, 50, 20)

## Concatenazioni multiple

Questo è già un modo per creare nuovi anelli. Tuttavia il vero potere arriva quando concateniamo assieme alcuni comandi.

Se volessimo mescolare l’anello, rimuovere 1 elemento e poi prendere i successivi 3?

Analizziamo passo dopo passo:

1. `(ring 10, 20, 30, 40, 50)` - il nostro anello inziale
2. `(ring 10, 20, 30, 40, 50).shuffle` - mescoliamo - `(ring 40, 30, 10, 50, 20)`
3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - rimuoviamo il primo elemento - `(ring 30, 10, 50, 20)`
4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - prendiamo gli ultimi tre - `(ring 30, 10, 50)`

Come puoi vedere, possiamo creare una lunga catena di questi metodi semplicemente collegandoli insieme. Possiamo farlo in qualsiasi ordine vogliamo per creare nuovi anelli partendo da anelli già esistenti.

## Immutabilità

Questi anelli hanno una proprietà molto potente e importante. Sono immutabili, il che significa che non possono cambiare. Questo significa che i metodi di concatenazione descritti in questa sezione non cambiano gli anelli ma ne creano di nuovi. Puoi condividere anelli tra i vari thread e cominciare a concatenarli all’interno del thread sapendo che non andrai a modificare gli altri thread in cui viene usato lo stesso anello.

## Metodi di concatenazione disponibili

Questa è una lista dei metodi di concatenazione a tua disposizione:

- `.reverse` - restituisce un anello invertito
- `.sort` - crea una versione ordinata dell’anello
- `.shuffle` - crea una versione mescolata dell’anello
- `.pick(3)` - restituisce un anello con i risultati della chiamata di `.choose` 3 volte
- `.pick(3)` - restituisce un anello con i risultati della chiamata di `.choose` 3 volte
- `.take(5)` - restituisce un anello che contiene solo i primi 5 elementi
- `.drop(3)` - restituisce un nuovo anello con tutti gli elementi eccetto i primi 3
- `.butlast` - restituisce un nuovo anello senza l’ultimo elemento
- `.drop_last(3)` - restituisce un anello senza gli ultimi 3 elementi
- `.take_last(6)`- restituisce un nuovo anello con soltanto gli ultimi 6 elementi
- `.stretch(2)` - ripete ogni elemento nell’anello due volte
- `.repeat(3)` - ripete l’intero anello 3 volte
- `.mirror` - aggiunge all’anello una versione invertita di se stesso
- `.reflect` - come mirror ma non duplica il valore di mezzo
- `.scale(2)` - restituisce un nuovo anello con tutti gli elementi moltiplicati per 2 (suppone che l’anello contiene solo numeri)

Ovviamente, questi metodi di concatenazione accettano anche altri valori! Sentiti libero di chiamare `.drop(5)` invece che `.drop(3)` se vuoi rimuovere i primi 5 elementi.