Rings

An interesting spin on standard lists are rings. If you know some programming, you might have come across ring buffers or ring arrays. Here, we’ll just go for ring - it’s short and simple.

In the previous section on lists we saw how we could fetch elements out of them by using the indexing mechanism:

puts [52, 55, 59][1]

Now, what happens if you want index 100? Well, there’s clearly no element at index 100 as the list has only three elements in it. So Sonic Pi will return you nil which means nothing.

However, consider you have a counter such as the current beat which continually increases. Let’s create our counter and our list:

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

We can now use our counter to access a note in our list:

puts notes[counter]

Great, we got 52. Now, let’s increment our counter and get another note:

counter = (inc counter)
puts notes[counter]

Super, we now get 55 and if we do it again we get 59. However, if we do it again, we’ll run out of numbers in our list and get nil. What if we wanted to just loop back round and start at the beginning of the list again? This is what rings are for.

Creating Rings

We can create rings one of two ways. Either we use the ring function with the elements of the ring as parameters:

(ring 52, 55, 59)

Or we can take a normal list and convert it to a ring by sending it the .ring message:

[52, 55, 59].ring

Indexing Rings

Once we have a ring, you can use it in exactly the same way you would use a normal list with the exception that you can use indexes that are negative or larger than the size of the ring and they’ll wrap round to always point at one of the ring’s elements:

(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

Using Rings

Let’s say we’re using a variable to represent the current beat number. We can use this as an index into our ring to fetch notes to play, or release times or anything useful we’ve stored in our ring regardless of the beat number we’re currently on.

Scales and Chords are Rings

A useful thing to know is that the lists returned by scale and chord are also rings and allow you to access them with arbitrary indexes.

Ring Constructors

In addition to ring there are a number of other functions which will construct a ring for us.

Take a look at their respective documentation for more information.