# Ł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ńcuchu poleceń `.reverse`, aby wziąć go i odwrócić:

    (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)

## Wielokrotność Ł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 poleceń w jeden łańcuch.

Co powiesz na to, aby najpierw przetasować pierścień, potem usunąć 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ć ich 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ściu nic nie stoi na przeszkodzie, abyś mógł współdzielić dany pierścień pomiędzy różnymi wątkami i wywoł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` - zwraca pierścień zawierający wyniki pojedynczego uruchomienia funkcji `.choose`
- `.pick(3)` - zwraca pierścień, który zawiera 3 losowo wybrane elementy z oryginalnego pierścienia (działanie analogiczne do funkcji `choose`)
- `.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ń, któ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
- `.scale(2)` - zwraca nowy pierścień, do którego zostają załadowane wszystkie elementy po uprzednim przemnożeniu przez 2 (przy założeniu, że pierścień ten zawiera tylko liczby)

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.