8.4 Ringe

# Ringe

Eine interessanter Dreh bei einfachen Listen sind Ringe. Wenn du ein bisschen Programmiererfahrung hast, bist du vielleicht schon einmal auf Ring-Buffer (Ringspeicher) oder Ring-Arrays gestoßen. Wir nennen sie hier - kurz und einfach - Ring.

Im vorherigen Abschnitt über Listen haben wir gesehen, wie wir über den Index-Mechanismus Elemente aus einer Liste holen können:

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

Was passiert jetzt wohl, wenn du den Index `100` abfragen willst? Nun, es gibt offensichtlich kein Element mit dem Index 100, da die Liste nur drei Elemente enthält. Also gibt Sonic Pi `nil` zurück, das steht für 'nichts'.

Stell dir jedoch vor, du hast einen Zähler, wie den aktuellen Beat (Schlag), der kontinuierlich wächst. Lass uns damit unseren Zähler und unsere Liste anlegen:

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

Wir können jetzt unseren Zähler verwenden, um auf eine Note in unserer Liste zuzugreifen:

```
puts notes[counter]
```

Super, da kam `52` heraus. Nun Lass uns den Zähler erhöhen (increment) und auf eine andere Note zugreifen:

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

Gut, jetzt kommt `55` und beim folgenden Mal `59` heraus. Wenn wir das jedoch noch einmal machen, werden wir keine Zahlen mehr in unserer Liste haben, und wir bekommen `nil` zurück. Was wäre, wenn wir in diesem Fall einfach wieder vom Anfang der Liste an zählen wollten? Genau dafür gibt es Ringe.

## Ringe erzeugen

Wir können Ringe auf zwei Arten erzeugen. Entweder wir nutzen die `ring`-Funktion, mit den gewünschten Elementen aus dem Rings als Parameter:

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

Oder wir nehmen eine normale Liste und wandeln sie mit der Nachricht `.ring` in einen Ring um:

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

## Ringe indizieren

Sobald du einen Ring hast, kannst du ihn genauso verwenden wie du eine normale Liste verwenden würdest, mit einer Ausnahme: Du kannst darauf auch solche Indizes verwenden, die negativ oder größer als der Ringinhalt sind - diese machen dann eine Schleife wieder zum Anfang, um immer auf ein Element des Rings zu verweisen:

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

## Ringe verwenden

Lass uns annehmen, wir verwenden eine Variable, die stets die aktuelle Schlagzahl abbildet. Wir können diese Variable in unserem Ring als Index verwenden, um so Noten, Release-Zeiten oder andere sinnvolle Dinge abzurufen, unabhängig davon bei welcher Schlagzahl wir uns gerade befinden.

## Skalen und Akkorde sind Ringe

Es ist nützlich zu wissen, das die Listen, die von `scale` und `chord` zurückgegeben werden, auch Ringe sind und du so mit beliebigen Indizes auf sie zugreifen kannst.

## Ring-Konstruktoren

Zusätzlich zu `ring` gibt es eine Anzahl weiterer Funktionen, die Ringe für uns erzeugen.

* `range` lädt dich dazu ein, einen Startpunkt, einen Endpunkt und eine Schrittgröße festzulegen.
* `bools` erlaubt dir `1`en und `0`en als Kurzform für boolesche Werte zu nutzen.
* `knit` erlaubt dir, eine Abfolge zu wiederholender Werte zu stricken (to knit).
* `spread` erzeugt einen Ring boolescher Werte in euklidischer Verteilung.

Für weitere Information sieh dir die Dokumentation zur jeweiligen Funktion an.

