この記事はfukuoka.ex Elixir/Phoenix Advent Calendar 2018 23日目の記事です。
こんにちは!Elixir学習中、業務では主に手動のテストをやっているyoshitakeです。
今回はAdvent Calendarの記事として、Elixirを学んで勉強中に知った小技を紹介します。
Elixirのパイプ演算子
僕が参考にしている、 @piacere_ex さんのExcelから関数型言語マスター1回目:データ行の”並べ替え”と”絞り込み” - Qiitaにもサラッと書かれていますが、Elixirにはパイプ演算子というものがあります。
これは、|>
でつなぐと、左側に記述した変数や関数の出力が、右側に書かれた関数の第一引数になる。
というものです。
簡単にパイプ演算子を使った例を紹介します。
def mul(a, b)do
a * b
end
def div(c, d)do
c / d
end
上記のように、2つの数値の掛け算・割り算を行う関数mul, divがそれぞれあったとします。
この関数を使って、 (5 × 4) / 10
を計算しその結果を表示する場合、パイプ演算子あり、なしではそれぞれ以下のようになります。
# パイプ演算子なし
IO.puts div(mul(5, 4), 10)
# パイプ演算子あり
mul(5,4)
|> div(10)
|> IO.puts
このパイプ演算子のおかげでデータの流れや変化がわかりやすい、というのが個人的な感想です。
直感的でわかりやすいなぁ…と思います。
しかし、このパイプ演算子は 次の関数の第一引数としてデータを渡すので、第一引数以外の引数にデータを渡す場合はちょっと工夫が必要とのことです。
そこでこの記事では、私が教えてもらった3通りのやり方を紹介します。
パイプ演算子で第一引数以外にデータを渡す方法
以下の3つの方法があるそうです。
- swapする関数を作る
- 匿名関数(無名関数)を使う
- 匿名関数(無名関数) + 省略記法(ショートハンド)を使う
先程の例 div(c,d)
に対して c/d
ではなく、d/c
をしたい、という処理について考えてみます。
1. swapする関数をつくる
def swap_div(c, d)
d / c
end
mul(5,4)
|> swap_div(10)
|> IO.puts
こんな感じです。
第一引数でもらうという事象は変更できないので、関数の中で順番を変更するですね。
2. 匿名関数(無名関数)を使う
mul(5, 4)
|> (fn n -> 10 /n end).()
|> IO.puts
Elixirには匿名関数(無名関数)をパイプ演算中に記述することができます。
それを記述し、その中で第一引数を他の処理に配置したコードを書いたらOKです。
■ 参考
関数 · Elixir School
3. 匿名関数(無名関数) + 省略記法を使う
mul(5, 4)
|> (&div(10, &1)).()
|> IO.puts
Elixirの匿名関数には省略記法があるそうで、省略記法を使うと第一引数を&1
第二引数を&2
という感じで使えるようになるそうです。
■ 参考
関数 · Elixir School
おわりに
さて、Elixir勉強中に習った小技を紹介しました。
これがなんの役に立ったのか?というと、Regex
(正規表現)を使っているときに役立ちました。
Regexをパイプ中に使ってたのですが、データを第二引数に渡したい!と思ったんですよね。
それについてはまたの機会に。
では、ここまで読んでいただきありがとうございました!
※ 他にも方法ある場合教えていただけると嬉しいです。
よろしくお願いします。
■ 参考
Regex – Elixir v1.7.4