標準のリストを一捻りした面白いものにリングがあります。いくつかのプログラミングを理解していれば、リングバッファやリングアレイなどを見たことがあるかもしれません。ここでは、まさにring
(環状リスト)について見ていきます - それは短く、簡単です。
リストに関する前のセクションでは、インデックスの機構を使用してリストから要素を取り出す方法を説明しました。
puts [52, 55, 59][1]
もしインデックス100を取り出そうとしら、何が起こるでしょう? まあ、3つの要素しか持たないリストの中でインデックス100の要素は、明らかにありません。だからSonic Piは空を意味するnil
を返すでしょう。
ここでは、現在のビート(拍子)が継続的に増加するcounter
を考えてみましょう。まずはカウンタとリストを作成します。
counter = 0
notes = [52, 55, 59]
これで、リストの音符にアクセスするためのカウンタを使用することができます。
puts notes[counter]
素晴らしい、52
を取得しました。カウンタを増やして別の音符を取得してみましょう。
counter = (inc counter)
puts notes[counter]
すごいでしょう、55
を取得し、それを再び繰り返すならば59
を得ます。さらに繰り返す場合は、リスト内の数が不足しnil
になるでしょう。では、ちょうどループのはじめに戻り、再びリストの先頭から開始したい場合はどうしたらようでしょうか? そのためにリングを使います。
リングは、2つの方法のどちらか1つで作成することができます。どちらの方法もリングの要素を引数とするring
関数を利用します。
(ring 52, 55, 59)
また、通常のリストを取得し、それに.ring
メッセージを送ることで、リングに変換することができます。
[52, 55, 59].ring
いったんリングを取得したら、通常のリストを使用する場合とまったく同じ方法で使用することができます。ただし、インデックスがマイナスもしくはリングの数値より大きい場合は、通常のリストと動作が異なり、先頭あるいは末尾に巻き戻ってリングの要素のどれか1つを必ず指します。
(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
はユークリッド分布に従ったブール値のリングを作成します。詳細については、個々のドキュメントを見てください。