Интересной разновидностью списков являются кольца. Если вы раньше занимались программированием, то наверняка сталкивались с кольцевым буфером или кольцевым массивом. Здесь мы узнаем про кольцевой список - это быстро и просто.
В предыдущем разделе о списках мы видели, как можно извлечь из них элементы, используя механизм индексирования:
puts [52, 55, 59][1]
Так, а что произойдет, если вы захотите извлечь индекс 100
? Там явно нет элемента с индексом 100, так как у нашего списка только три элемента. Поэтому Sonic Pi вернет вам nil
, что означает “ничто”.
Однако, представьте, что у вас есть счётчик, который, подобно номеру текущего такта, постоянно увеличивается. Давайте создадим наш счётчик и наш список:
counter = 0
notes = [52, 55, 59]
Теперь мы можем использовать счётчик, чтобы получить доступ к нотам в нашем списке:
puts notes[counter]
Здорово, мы получили 52
. Теперь давайте увеличим наш счётчик и получим другую ноту:
counter = (inc counter)
puts notes[counter]
Супер, теперь мы получили 55
и если мы сделаем так снова, получим 59
. Однако, если после этого мы увеличим счётчик ещё раз, мы выйдем за пределы нашего списка и получим nil
. Но что, если нам нужно вернуться к началу списка и снова начинать извлекать элементы по кругу? Вот для этого и нужны кольца.
Мы можем создавать кольца одним из двух способов. Либо используем функцию ring
с элементами кольца в качестве параметров:
(ring 52, 55, 59)
Либо можем взять обычный список и преобразовать его в кольцо, передав ему .ring
сообщение:
[52, 55, 59].ring
Как только мы получили кольцо, мы можем использовать его точно так же, как если бы мы использовали обычный список, за исключением того, что можно использовать отрицательные индексы и индексы, превышающие размеры кольца. И они будут повторяться по кругу и всегда указывать на один из элементов кольца:
(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
Допустим, мы используем переменную для хранения номера текущего такта. Мы можем использовать её в качестве индекса в нашем кольце для извлечения нот, или времени затухания или чего-нибудь полезного, что мы сохранили в нашем кольце, независимо от номера такта, в котором мы находимся в данный момент.
Полезно знать, что списки, возвращаемые scale
и chord
также являются кольцами и позволяют получить к ним доступ с помощью произвольных индексов.
В дополнение к ring
существует ряд других функций, которые будут создавать кольца для нас.
range
предлагает вам указать начальную точку, конечную точку и размер шага.bools
позволяет использовать 1
и 0
, чтобы кратко представлять логические переменные.knit
позволяет связывать в последовательности повторяющиеся значения.spread
создает кольцо логических значений с Евклидовым распределением.Взгляните на их соответствующую документацию для получения дополнительной информации.