8.4 Pierścienie

# Pierścienie

Ciekawym przypadkiem stanardowych list są pierścienie. Jeśli 
znasz się trochę na programowaniu, to mogło się zdarzyć, że miałeś do 
czynienia z buforami cyklicznymi lub tablicami cyklicznymi. Tutaj 
przyjrzymy się tylko pierścieniowi - jest krótki i prosty.

W poprzedniej sekcji dotyczącej list widzieliśmy w jaki sposób możemy 
wyciągać z nich elementy korzystając z mechanizmu indeksowania:

```
puts [52, 55, 59][1]
```

A co się stanie jeśli chciałbyś pozycję spod indeksu `100`? Dobrze, więc 
na pozycji 100 nie ma żadnego elementu jako, że lista posiada w sobie
tylko trzy elementy. Sonic Pi zwróci więc wartość `nil` co oznacza nic.

Jednakże, biorąc pod uwagę, że masz licznik, taki jak aktualne uderzenie, 
które nieustannie rośnie. Spróbujmy utworzyć sobie licznik oraz listę: 

```
counter = 0
notes = [52, 55, 59]
```

Możemy teraz użyć naszego licznika aby dostać się do nuty znajdującej 
się w naszej liście:

```
puts notes[counter]
```

Super, otrzymaliśmy `52`. Teraz, spróbujmy zwiększyć nasz licznik 
i dostać się do kolejnej nuty: 

```
counter = (inc counter)
puts notes[counter]
```

Super, teraz otrzymaliśmy `55` i jeśli zrobimy to jeszcze raz, to otrzymamy 
liczbę `59`. Jednakże, jeśli zrobimy to kolejny raz, to wyskoczymy poza 
liczby znajdujące się w naszej liście i otrzymamy `nil`. A co jeśli 
chcieliśmy tylko zrobić pętlę, wrócić do początku i zacząć na samym początku 
listy od nowa? Do tego właśnie służą pierścienie.

## Tworzenie Pierścieni

Możemy tworzyć pierścienie na dwa sposoby. Albo użyjemy funkcji `ring` podając 
elementy dla danego pierścienia jako parametry: 

```
(ring 52, 55, 59)
```

Albo możemy wziąć normalną listę i przekształcić ją w pierścień poprzez 
wysłanie do niej wiadomości `.ring`: 

```
[52, 55, 59].ring
```

## Indeksowanie Pierścieni

Gdy już masz pierścień, możesz go używać dokładnie w ten sam sposób 
w jaki używasz normalnej listy z tym jednym wyjątkiem, że możesz używać 
indeksów ujemnych oraz takich, które są większe niż ilość elementów 
w danym pierścieniu a będą one powtarzać się cyklicznie i zawsze będą 
wskazywać na jeden z elementów pierścienia:

```
(ring 52, 55, 59)[0] #=> 52
(ring 52, 55, 59)[1] #=> 55
(ring 52, 55, 59)[2] #=> 59
(ring 52, 55, 59)[3] #=> 52
(ring 52, 55, 59)[-1] #=> 59
```

## Korzystanie z Pierścieni

Przyjmijmy, że używamy zmiennej do reprezentacji aktualnego 
numeru uderzenia. Możemy użyć jej jako indeksu w naszym pierścieniu 
aby wydobywać kolejne nuty do zagrania, czasy zanikania albo cokolwiek 
innego przydatnego co załadowaliśmy do naszego pierścienia niezależnie 
od numeru uderzenia (beat) przy którym aktualnie się znajdujemy.

## Skale i Akordy są Pierścieniami

Przydatną rzeczą jest wiedza o tym, że listy zwracane przez skale `scale` 
oraz akordy `chord` są również pierścieniami i pozwalają Ci na dostęp 
do nich z wykorzystaniem bezwzględnych indeksów.

## Konstruktory Pierścieni

Oprócz funkcji `ring` istnieje również kilka innnych funkcji, które 
pozwalają nam na tworzenie pierścieni.

* `range` wymaga abyś określił punkt startu, końca oraz rozmiar kroku
* `bools` pozwala Ci na użycie wartości `1` i `0` aby treściwie reprezentować 
wartości logiczne (boolean)
* `knit` pozwala Ci na spajanie sekwencji powtarzalnych wartości
* `spread` tworzy pierścień wartości logicznych o rozkładzie Euklidesowym

Przyjrzyj się poszczególnym dokumentacjom dla uzyskania większej 
ilości informacji. 
