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.

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