一度、膨大なコードを書き始めると、それらの構造をより簡単かつ整理された状態で把握できるように、構築しまとめたいと感じることになるでしょう。ファンクション(関数)はそんなことをとても効果的に成し遂げる方法です。この関数を使うとコードのまとまりに対して名前をつけることも可能になります。早速、見ていきましょう。
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 が使われています。
関数によって、高度な表現と沢山の構造を簡単に読み込ませることが出来るということがわかりましたね!