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

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

## 関数の定義

    define :foo do
      play 50
      sleep 1
      play 55
      sleep 2
    end

ここでは`foo`という名前を付けた新しい関数を定義しています。この章ではすっかりお馴染みのdo/endブロックと、`define`という魔法の言葉の後ろに、この関数に付けたい名前を続けています。関数の名前は`foo`である必要はなく、`bar`や`baz`といったどんなものでも構いませんが、理想的には`main_section`や`lead_riff`といった何か意味のあるものがよいでしょう。

関数を定義するとき、その名前に`:`（コロン）を付加することを忘れないでください。

## 関数の呼び出し

いったん1つの関数を定義すると、ただ名前を書くことでそれを呼びだすことができます。

    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`を超えた関数の利用

これまでのところ、`Run`ボタンを押すたびに、Sonic Piを完全に白紙の状態から始めたことにして、表示されているBuffer以外のコードは無いものとしていました。これは、別のBufferまたは別のスレッド内のコードを参照できなかったからです。しかし、関数はそれを変えることができます。あなたが関数を定義すると、Sonic Piはそれを覚えることができます。では、ちょっとやってみましょう。まずBufferにあるすべてのコードを消して、次のものに変更します。

    foo

`Run`ボタンを押して、関数の`foo`が再生されることを確認してください。コードはどこにいったのでしょう？ また、Sonic Piは、実行の仕方をどのように知っていたのでしょうか？ Sonic PiはBufferを消したあとでも、あなたが打ち込んだ関数を覚えていて、定義した関数をしっかりと再生してみせたのです。この動作は`define`もしくは`defonce`を使用した時にだけ働く機能です。

## 引数の付いた関数

最小値と最大値の情報を`rrand`へ渡すように、引数を受け取る関数についても興味を持つかもしれません。ちょっと見てみましょう。

    define :my_player do |n|
      play n
    end
    my_player 80
    sleep 0.5
    my_player 90

この例はあまり面白いものではありませんが、ポイントとなる点を示しています。ここでは、引数の付いた`my_player`という名前の関数を、`play`の独自のバージョンとして作成しています。

この引数は`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`という行の中で1つの数値のように`repeats`が使われます。また、`play`を呼び出した際の音符の名前と同じように`root`が使われています。

関数に多くの処理を移動することによって、コードをとても表現力豊かにかつ読み易く書けることがわかりましたね！