Part13:関数

希「Elixirは関数型言語や。つまり、今回やる関数が、Elixirの中心になってくるってことや」
凛「なんか大変そうだにゃ・・・」
希「案外そうでもないんよ。そりゃ、難しいこと考え始めるときりがないけど、関数の定義と呼び出しの基本はそう難しくないで」

希「実例を見ればすぐわかるかな」

海未「例がひどすぎるのではないでしょうか」
凛「抗議したいけど凛には適当なセリフがないから諦めるにゃ」
希「defmoduleは、関数をグループ化しておくためのモジュールの定義や。ここだとIdolって名前のモジュールを定義しとる」
海未「流されました・・・」
希「関数はモジュールの中にしか書けないから、まずはdefmoduleで意味的なまとまりを考えたモジュールを定義する」
凛「ただの入れ物?」
希「言ってみれば小分け容器やね。それと、モジュール名は大文字で始めるのが決まりや」
凛「じゃあ簡単にゃ」

希「defを使って関数を定義する。関数名、引数、最後にdo~endのブロックや」
海未「引数nameを取るnico関数ですね」
希「そういうこと。で、ブロックの中身が実行されて、最後の文の評価結果が戻り値になる」
海未「それでその恥ずかしい文字列が戻ってくるわけですね・・・」
希「それと、関数名は小文字で始めるのが決まりや」

希「関数を呼び出す方は、いままで散々見てきたはずや。IO.putsとかString.lengthとか色々あったやろ?」
海未「そういえば・・・それも関数でした」
希「モジュール名.関数名 引数で呼び出せる。IOとかStringはモジュールの名前や」
凛「あんまり考えずに使ってたけど、そういうことだったんだね」
希「Idol.nico "海未ちゃん"や」

希「で、関数の定義や呼び出しには、()を使うこともできる」

希「これはお好みや。動作には影響もないから、読みやすさで選ぶとええ。かっこなしが主流みたいやから、ここではかっこなしでいくで」
海未「どちらがよい、というわけではなさそうですね」
凛「目玉焼きには塩ですか醤油ですかレベルの話だにゃ」
希「ウチはソースや」
凛「そんなことは聞いてないにゃ!」
希「ただし、時々かっこがないとだめなことがあるから注意や」

希「関数nicoはどこからでも呼べたけど、制限も付けられる。defpを使うと、モジュール内からしか呼び出せなくなるんや」

希「関数nicoはdefpで定義したnico_internalを呼び出すだけにした。元の処理はそのままnico_internalに移動してる」
海未「モジュール内の関数を呼ぶ場合はモジュール名はいらないのですね」
希「自明やからね。さて、これで海未ちゃんの方は元通りに動いてる。問題は凛ちゃんにゃ」
凛「凛は何もしてないにゃ」
希「エラー吐いてるやろ?それは、defpで定義した関数をモジュールの外から呼ぼうとしてるからや」
海未「あえて呼び出せなくする理由はあるのですか?」
希「APIと内部実装を分けるって話やね。defで定義する関数はAPIで、外から呼ばれることを想定している。つまり、滅多なことでは変更できなくなるってことや。外部から依存されとるからね」
海未「たしかに、モジュールの仕様が変わっては、利用しているコードも書き直さないといけませんね」
希「せや。けどdefpで定義した関数は違う。モジュールを書いた人の完全なコントロール下にあるわけや。だからAPIに影響しない範囲でいつでも自由に変更できるし、モジュールの利用者はそれに関知する必要はない」
海未「なるほど。技術的というより、規約の問題なのですね」

希「同じ名前の関数を複数定義できるんやけど、それをコントロールするのにガード節を使う。ガードは前回出てきたな?」

凛「関数が呼び出される時点で条件分岐されてるんだね」
希「引数はデフォルト値も決めておけてな」

希「\\で区切ってデフォルト値を書いておくと、引数が指定されなかった場合にその値が使われる」

希「さて・・・ここまで見てきたのは名前付きの関数や。けど、無名関数とか匿名関数と呼ばれるものもよく使われる。それを見ていこうか」

希「fnを使って匿名関数を定義して、その関数を変数に代入したりとかできる」
海未「defで定義するのではだめなのですか?」
希「こっちは使い捨てが多いかな。その場でしか使わない関数を用意するのに便利や」

希「たとえばこのEnum.mapや。リストの各要素に、第2引数で渡した関数を適用した結果のリストが得られる」
凛「えーと、x <> xで同じ文字列を2つつなげる匿名関数があって、”うみ”と”りん”と”のぞ”を渡すと、”うみうみ”と”りんりん”と”のぞのぞ”になるにゃ!」
希「Elixirの標準ライブラリには関数を引数に取る関数がたくさんあるし、自分で作るときにもよく使うテクニックやから、しっかり覚えておくことや」
凛「はーい!」

希「これで関数の基礎は終わりや。あとは先に進めながらちょっとずつ応用を覚えていけばええ」
凛「そんなに難しくなかったにゃ」
海未「次回は凛の版ですね」
凛「じゃあ、繰り返しをやるにゃ!」


LINEで送る
Pocket


返信を残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です