# Cadenas de Anillos

Otra forma de crear nuevos anillos, además de con constructores como `range` y `spread`, es manipulando anillos existentes.

## Comandos de Cadenas

Para explorar esta idea, mira el siguiente anillo:

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

¿Y si lo queremos de atrás a delante? Bueno, sólo tendríamos que usar el comando `.reverse` para coger el anillo y darle la vuelta:

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

Ahora bien, ¿y si queremos los tres primeros valores del anillo?

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

Finalmente, ¿y si queremos mezclar (barajar) el anillo?

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

## Cadenas Múltiples

Por sí sola, ésta es una forma muy potente de crear nuevos anillos. Sin embargo, el verdadero poder viene cuando encadenas unos cuantos de estos comandos juntos.

¿Y qué me dices de desordenar el anillo, quitarle 1 elemento, y después coger los siguientes 3?

Veamos esto por pasos:

1. `(ring 10, 20, 30, 40, 50)` - nuestro anillo inicial
2. `(ring 10, 20, 30, 40, 50).shuffle` - lo desordenamos - `(ring 40, 30, 10, 50, 20)`
3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - quitamos 1 - `(ring 30, 10, 50, 20)`
4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - cogemos 3 - `(ring 30, 10, 50)`

¿Ves cómo hemos creado una cadena larga de estos métodos con sólo unirlos? Podemos combinarlos en el orden que queramos; ésta es una forma extremadamente rica y potente de generar nuevos anillos a partir de anillos existentes.

## Inmutabilidad

Estos anillos tienen una propiedad muy poderosa e importante. Son inmutables, es decir, no pueden cambiar. Esto significa que la cadena de métodos descrita en esta sección no cambia anillos, sino que crea nuevos anillos. Por eso, puedes compartir anillos entre distintos hilos con total libertad; puedes encadenarlos dentro de un hilo sabiendo que ningún otro hilo usando el mismo anillo se va a ver afectado.

## Métodos de Cadenas Disponibles

Aquí tienes una lista de los métodos de cadenas disponibles, para que juegues con ellos:

- `.reverse` - devuelve una versión del anillo dado la vuelta
- `.sort` - crea una versión ordenada del anillo
- `.shuffle` - crea una versión desordenada del anillo
- `.pick(3)` - devuelve un anillo que es el resultado de llamar `.choose` 3 veces
- `.pick(3)` - devuelve un anillo que es el resultado de llamar `.choose` 3 veces
- `.take(5)` - devuelve un anillo nuevo, que sólo contiene los primeros 5 elementos
- `.drop(3)` - devuelve un anillo nuevo con todos los elementos salvo los 3 primeros
- `.butlast` - devuelve un anillo nuevo sin el último elemento
- `.drop_last(3)` - devuelve un nuevo anillo sin los 3 últimos elementos
- `.take_last(6)`- devuelve un anillo nuevo con sólo los últimos 6 elementos
- `.stretch(2)` - repite cada elemento en el anillo dos veces
- `.repeat(3)` - repite el anillo entero 3 veces
- `.mirror` - añade el anillo a una versión invertida del mismo
- `.reflect` - lo mismo que mirror, pero no duplica el valor del medio
- `.scale(2)` - devuelve un anillo nuevo con todos los elementos multiplicados por 2 (asume que el anillo sólo contiene números)

Por supuesto, estos métodos para cadenas con números, ¡pueden utilizar otros númros cualquiera! Así que, siéntete libre de llamar `.drop(5)` en vez de `.drop(3)` si quieres quitar los primeros 5 elementos.