# Cadeia de anéis

Para além de construtores como `range` e `spread` outra maneira de criar novos anéis é manipular anéis existentes.

## Cadeia de comandos

Para explorar isto, vê este anel simples:

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

E se o quisermos ao contrario? Usamos a cadeia de comando `.reverse` para pegar no anel e o rodar:

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

Agora, e se quisermos os 3 primeiros valores do anel?

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

Finalmente, e se quisermos baralhar o anel?

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

## Múltiplas cadeias

Isto já é uma maneira poderosa de criar novos anéis. No entanto, o poder real vem quando encadeias alguns destes comando em conjunto.

Que tal baralhar o anel, largar o 1 elemento e obter os 3 posteriores?

Vamos fazer isso por etapas:

1. `(ring 10, 20, 30, 40, 50)` - o nosso anel inicial
2. `(ring 10, 20, 30, 40, 50).shuffle` - baralhar - `(ring 40, 30, 10, 50, 20)`
3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - retira 1 - `(ring 30, 10, 50, 20)`
4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - obtem 3 - `(ring 30, 10, 50)`

Como podes ver acabamos de criar uma cadeia longa destes métodos adicionando-os em conjunto. Podemos combinar estes em qualquer ordem criando uma maneira extremamente rica e poderosa de gerar novos anéis a partir de existentes.

## Imutabilidade

Estes anéis têm uma poderosa e importante propriedade. Eles são imutáveis o que significa que não podem mudar. o que quer dizer que encadeando estes métodos descritos nesta secção não mudam os anéis apenas criam novos anéis. Isto significa que estas livre de partilhar anéis entre threads e começar a encadear-los dentro de um thread sabendo que não irá afectar outros threads que estejam a usar o mesmo anel.

## Cadeias de métodos disponíveis

Aqui está uma lista de cadeia de métodos disponíveis para brincares:

- `.reverse` - devolve uma versão invertida do anel
- `.sort`- cria uma versão ordenada do anel
- `.shuffle` - cria uma versão baralhada do anel
- `.pick(3)` - devolve um anel com o resultado de chamar `.choose` 3 vezes
- `.pick(3)` - devolve um anel com o resultado de chamar `.choose` 3 vezes
- `.take(5)`- devolve um novo anel contendo apenas os primeiros 5 elementos
- `drop(3)`- devolve um novo anel com tudo excepto os 3 primeiros elementos
- `butlast` - devolve um novo anel sem o ultimo elemento do anel original
- `.drop_last(3)` - devolve um novo anel com os 3 últimos elementos originais em falta
- `take_last(6)` - devolve um novo anel com apenas os últimos 6 elementos originais
- `.stretch(2)` - repete 2 vezes cada elemento do anel original
- `.repeat(3)` - repete todo o anel original 3 vezes
- `.mirror` - adiciona ao anel original uma versão revertida dele próprio
- `.reflect`- o mesmo que mirror mas não duplica o valor do meio do anel
- `.scale(2)` - devolve um novo anel com todos os elementos multiplicados por 2 (assumindo que o anel apenas contem números)

Claro que estes métodos em cadeia podem receber também outros números. És livre de chamar `.drop(5)` em vez de `.drop(3)`se quiseres largar os primeiros 5 elementos.