5.5 関数

# ファンクション（関数）

一度、膨大なコードを書き始めると、それらの構造をより簡単かつ整理された状態で把握できるように、構築しまとめたいと感じることになるでしょう。`ファンクション`（関数）はそんなことをとても効果的に成し遂げる方法です。この関数を使うとコードのまとまりに対して名前をつけることも可能になります。早速、見ていきましょう。

## 関数の定義

```
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を完全に白紙の状態からはじめました。
これまでワークスペースをなぜとり除いているかについては触れてきませんでした。
これは１つのワークスペースのみで再生されていたからで、別のワークスペース
または別のスレッド内のコードを参照することはできなかったからです。
しかし、関数はそれを変えることができます。あなたが関数を定義すると、
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` が使われています。

関数によって、高度な表現と沢山の構造を簡単に読み込ませることが出来るということがわかりましたね！
