Eine interessante Spielart von normalen Listen sind Ringe. Wenn Du ein bisschen Programmiererfahrung hast, könntest Du Ringspeicher (engl. ‘Ring Buffer’) oder Ring-Arrays kennen. Wir nennen die hier nur Ring - das ist kurz und einfach.
Im vorherigen Abschnitt über Listen haben wir gesehen, dass wir Elemente aus einer Liste über den Index holen können:
puts [52, 55, 59][1]
Was passiert jetzt wohl, wenn Du den Index 100
abfragen willst?
Offensichtlich gibt es kein Element mit dem Index 100, da die Liste nur
drei Elemente enthält. Also gibt Sonic Pi nil
zurück, was “nichts”
bedeutet. Stell Dir vor, einen Zähler wie den aktuellen Takt zu haben,
der kontinuierlich wächst. Lass uns so einen Zähler und unsere Liste
anlegen:
counter = 0
notes = [52, 55, 59]
Jetzt können wir mit unserem Zähler auf eine Note in unserer Liste zugreifen:
puts notes[counter]
Super, da kam 52
heraus. Jetzt erhöhen wir den Zähler (inc
, die
Abkürzung für englisch “to increment” = erhöhen) und bekommen damit
eine neue Note:
counter = (inc counter)
puts notes[counter]
Ok, jetzt kommen 55
und beim nächsten Mal 59
heraus. Wenn wir das
jedoch jetzt noch einmal machen, werden wir aber nicht mehr genug Zahlen
in unserer Liste haben und werden stattdessen nil
zurück bekommen.
Was wäre, wenn wir dann einfach wieder vom Anfang der Liste anfangen
wollten? Genau dafür gibt es Ringe.
Es gibt zwei Möglichkeiten, Ringe zu erzeugen. Die erste ist, die
ring
Funktion mit den gewünschten Elementen des Rings als Parameter
zu verwenden:
(ring 52, 55, 59)
Die zweite Möglichkeit ist es, eine normale Liste mit der Nachricht
.ring
zu einem Ring umzuwandeln:
[52, 55, 59].ring
Sobald wir einen Ring haben, können wir ihn auf die gleiche Art wie eine Liste verwenden. Die einzige Ausnahme ist, dass Du Indizes verwenden kannst, die negativ oder größer als der Ringinhalt sind. Diese fangen dann wieder am Anfang an, um immer auf ein Element des Rings zu zeigen:
(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
Angenommen, wir bilden die Nummer des aktuellen Takts in einer Variable ab. Diese Nummer können wir als Zugriffsindex für unseren Ring verwenden, um abzuspielende Note, Release-Zeiten oder andere sinnvolle Dinge, die wir in unserem Ring abgelegt haben, abzurufen.
Gut zu wissen: Die Listen, die von scale
und chord
zurückgegeben
werden, sind Ringe. Du kannst also mit beliebigen Indizes auf sie
zuzugreifen.
Zusätzlich zu ring
gibt es noch eine Anzahl weiterer Funktionen, die
Ringe für uns erzeugen:
range
lädt ein, einen Startpunkt, einen Endpunkt und eine Schrittgröße zu definieren.bools
erlaubt Dir 1
er und 0
er als prägnante Darstellung boolscher Werte zu nutzen.knit
erlaubt Dir, eine Abfolge wiederholter Werte zu “stricken” (engl. “to knit”).spread
verteilt boolschen Werte mit dem Euklidischen Algorithmus in einem Ring.Mehr Informationen zu diesen Funktionen findest Du in der entsprechenden Dokumentation.