8.5 Łańcuchy Pierścieni (Ring Chains)

Oprócz konstruktorów takich jak `range` i `spread` innym sposobem 
tworzenia nowych pierścieni jest manipulowanie i modyfikacja istniejących 
pierścieni (rings).

## Łańcuchy poleceń (Chain Commands)

Aby zbadać ten temat stwórzmy prosty pierścień: 

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

Co jeśli chcielibyśmy otrzymać wszystkie elementy tego pierścienia 
w odwrotnej kolejności? Wystarczy, że użyjemy w łańuchu poleceń 
`.reverse` aby wziąć nasz pierścień i odwrócić go:

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

A co, jeśli teraz potrzebujemy tylko pierwsze trzy elementy 
z naszego pierścienia?

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

I na koniec jeszcze jedno, co jeśli chcielibyśmy przetasować 
elementy naszego pierścienia tak jak tasujemy karty przed grą?

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

## Wiele Łańcuchów

Powyższe polecenia dają bardzo duże możliwości tworzenia nowych pierścieni (rings). 
Jednakże, *prawdziwa* moc pojawia się dopiero w momencie, gdy połączysz kilka 
poleceni w jeden łańcuch.

Co powiesz na to aby najpierw przetasować pierścień, potem usunać z niego 
1 element i z elementów, które pozostały wybrać tylko pierwsze 3?

Zróbmy to krok po kroku: 

1. `(ring 10, 20, 30, 40, 50)` - nasz początkowy pierścień
2. `(ring 10, 20, 30, 40, 50).shuffle` - tasujemy - `(ring 40, 30, 10, 50, 20)`
3. `(ring 10, 20, 30, 40, 50).shuffle.drop(1)` - usuwamy 1-wszy element - `(ring 30, 10, 50, 20)`
4. `(ring 10, 20, 30, 40, 50).shuffle.drop(1).take(3)` - pozostawiamy tylko pierwsze 3 - `(ring 30, 10, 50)`

Widzisz jak łatwo możemy stworzyć długi łańcuch tych metod  *sklejając 
je po prostu razem*? Możemy użyć tych metod w dowolnej kolejności 
na jaką nas tylko najdzie ochota. Dzięki temu mamy bardzo bogatą 
i potężną paletę sposobów, dzięki którym możemy tworzyć nowe pierścienie 
z już istniejących.

## Niezmienność

Pierścienie posiadają pewną potężną i ważną cechę. Są niezmienne co 
oznacza, że gdy raz zostaną już utworzone to nie mogą zostać zmienione. 
Z tego wynika, że łańcuchy wywołań metod opisane w tym rozdziale 
*nie zmieniają pierścieni* lecz *tworzą nowe pierścienie*. Dzięki takiemu 
podejśćiu nic nie stoi na przeszkodzie abyś mógł współdzielić dany 
pierścień pomiędzy różnymi wątkami i wywyływać na nim łańcuchy metod 
w ramach jednego wątku, gdyż wiesz że nie wpłynie to w żaden sposób 
na jakikolwiek inny wątek, który korzysta z tego samego pierścienia.

## Dostępne Łańcuchy Metod

Oto lista metod, które możesz łączyć w łańcuchy wywołań:

* `.reverse` - zwraca odwróconą wersję pierścienia
* `.sort`    - tworzy posortowaną wersję pierścienia
* `.shuffle` - tworzy pierścień z wartościami, które są przetasowane
* `.pick(3)` - zwraca pierścień, który zawiera 3 losowo wybrane elementy z oryginalnego pierścienia (działanie analogiczne do funkcji `choose`)
* `.pick`    - działanie analogiczne do funkcji `.pick(3)`, z tym że w tym przypadku liczba wylosowanych elementów jest równa ilości elementów znajdujących się w oryginalnym pierścieniu  
* `.take(5)` - zwraca nowy pierścień, który zawiera tylko 5 pierwszych elementów
* `.drop(3)` - zwraca nowy pierścień, który zawiera wszystkie elementy oprócz pierwszych 3 
* `.butlast` - zwraca nowy pierścień, który nie zawiera ostatniego elementu 
* `.drop_last(3)` - zwraca nowy pierścień, kóry nie zawiera 3 ostatnich elementów
* `.take_last(6)`- zwraca nowy pierścień, który posiada tylko 6 ostatnich elementów
* `.stretch(2)` - powtarza każdy z elementów w pierścieniu dwukrotnie
* `.repeat(3)` - powtarza cały pierścień trzykrotnie
* `.mirror` - dodaje pierścień do odwróconej wersji samego siebie
* `.reflect` - działa tak samo jak mirror, ale nie powtarza środkowej wartości z pierścienia

Oczywiście, metody które przyjmują jako parametr liczbę, mogą przyjmować 
też inne liczby! Nie krępuj się więc i spróbuj wywołać metodę `.drop(5)` 
zamiast widocznej parę linijek wyżej metody `.drop(3)`. Pozwoli Ci to stworzyć 
nową listę, która nie będzie zawierała 5 pierwszych elementów.
