一度、膨大なコードを書き始めると、それらの構造をより簡単かつ整理された状態で把握できるように、構築しまとめたいと感じることになるでしょう。ファンクション
(関数)はそんなことをとても効果的に成し遂げる方法です。この関数を使うとコードのまとまりに対して名前をつけることも可能になります。早速、見ていきましょう。
define :foo do
play 50
sleep 1
play 55
sleep 2
end
ここではfoo
と呼ばれている新しい関数を見ていきます。これは以前から出てきているdo/endブロックと、define
という魔法の言葉とともに働きます。しかしbar
やbaz
や、main_section
やlead_riff
のようなある程度の意味を持った関数が呼び出せれば、foo
を呼び出す必要はありませんでした。
それを定義するとき、関数の名前に:
(コロン)を付加することを忘れないでください。
いったん一つの関数を定義すると、ただ名前を書くことでそれを呼びだすことができます。
define :foo do
play 50
sleep 1
play 55
sleep 0.5
end
foo
sleep 1
2.times do
foo
end
foo
は、イテレーション(繰り返し)ブロック内のplay
やsample
などの書かれたコード内やどこからでも使うことができます。
この関数は、楽曲の中で自分自身を新しい意味ある言葉として定義し、それ自身を表現する際に非常に優れた方法です。
これまでのところ、Run
ボタンを押すたびに、Sonic Piを完全に白紙の状態からはじめました。
これまでワークスペースをなぜとり除いているかについては触れてきませんでした。
これは1つのワークスペースのみで再生されていたからで、別のワークスペース
または別のスレッド内のコードを参照することはできなかったからです。
しかし、関数はそれを変えることができます。あなたが関数を定義すると、
Sonic Piはそれを覚えることができます。では、ちょっとやってみましょう。
まずワークスペースにあるすべてのコードを消して、foo
と名づけたものに変更します。
foo
Run
ボタンを押して、関数のfoo
が再生されることを確認してください。
コードはどこにいったのでしょう?また、Sonic Piは、実行の仕方を
どのように知っていたのでしょうか?Sonic Piはワークスペースを消したあとでも、
あなたが打ち込んだ関数を覚えていて、定義した関数ををしっかりと再生してみせたのです。
この動作はdefine
もしくはdefonce
を使用した時にだけ働く機能です。
最小値と最大値の情報をrrandへ渡すように、変動する引数を受け取る面白い関数をご紹介しましょう。 それでは見てみましょう。
define :my_player do |n|
play n
end
my_player 80
sleep 0.5
my_player 90
この点を解説するのはとても難しいのですが、ポイントを説明します。
play
をmy_player
という関数として定義します。
この変数はdefine
で括られたdo/endブロックのdoの後に記述する必要があります。
変数は、垂直のバー|
で囲み、複数の変数を扱う場合はカンマ ,
で分割し、
変数の名前はどんな言葉でもつけることが出来ます。
この魔法は、define
を使いdo/endブロック内で行われます。
また、実行されるための値のような変数名を使うことも出来ます。
この例で言うと、n
という関数になります。コードが起動した際のひとつの約束ごととして、
変数はその領域に記憶されている実際の数値に置き換えられます。
あなたが関数を呼び出した際は、この数値を関数に置き換えて実行することが出来るのです。
このmy_player 80
というのは、音階80の音を鳴らすということです。
関数の定義の中で、n
はすぐに80
に置き換えられます。
そしてplay n
はplay 80
となるのです。また次にmy_player 90
という関数を呼び出す際には、
n
はすぐさま90
に置き換えられ、play n
はplay 90
として再生されます。
それではさらにおもしろい例を見てみましょう。
define :chord_player do |root, repeats|
repeats.times do
play chord(root, :minor), release: 0.3
sleep 0.5
end
end
chord_player :e3, 2
sleep 0.5
chord_player :a3, 3
chord_player :g3, 4
sleep 0.5
chord_player :e3, 3
ここでは repeats.times do
という行の中で一つの数値のように repeats
が使われます。
また、 play
を呼び出した際の音階の名前と同様に root
が使われています。
関数によって、高度な表現と沢山の構造を簡単に読み込ませることが出来るということがわかりましたね!