自衛官からエンジニアへ Elixirから始める Web開発 Part16

この記事は「Elixir Advent Calendar 2023」16日目の記事です
東京にいるけどfukuokaexのYOSUKEです。

普段は 合同会社TheWaggle で教材開発・システム開発・研修講師などマルチに活動してます。

このシリーズでは、文系ですらない、体育会系でも始められるプログラミング学習　というテーマで元自衛官だった僕が
自衛官からエンジニアになってもらいたいという気持ちを込めて、普段は大人しいですが、このコラムシリーズでは、あえて、体育会系のノリで、貴様ら理屈で覚えるなら体で覚えろ！というノリで書いてみたいと思います。

なので、初学者向けですが、理論は後回し、まずは動かして体感しろってノリの第16回目です。

それでは、いくぞ！

## 貴様らが今日やるのは「引数のパターンマッチ」だ！

よし、貴様ら良く寝てきたか？ 体調管理も立派な仕事の内だ、平時は22時には寝て、朝6時に起床し、朝走って身体を鍛えておくように！

よし、それでは前回作成した関数を改造して、他の材料も追加していくとしよう。

```elixir
defmodule TNT do
    def create_c4(rdx) do
        rdx
    end
end
```

前回は、rdxだけを投入した形だ、しかし、RDXは爆薬でかつ、とても扱い難い。慎重に扱わなければならない爆薬だからだ。
これでは任務に持っていくのに非常に怖い！そこで、他の成分を入れて扱いやすいC4爆弾を作成していくわけだ。

その為に、以下の成分を全て関数に入れられるように入り口を準備しろ！

```elixir
{"RDX", "45.5g"}
{"ポリイソブチレン", "10.5g"}
{"モーターオイル", "0.8g"}
{"セバシン酸ジオクチル", "2.65g"}
{"ガソリン", "25ml"}
```

* はい、できました！

```elixir
defmodule TNT do
    def create_c4(rdx,rdx,rdx,rdx,rdx) do
        rdx
    end
end
```

貴様！全ての成分をrdxにするきか？

* いえ、入り口なので、とりあえず5つ入れる場所ができれば良いかと思って。

貴様のその腐った根性を一から叩き直してくれる。腕立て伏せ100回だ！

いいか、貴様ら、変数、引数、関数名など自由に決められるからと言って、楽をしようなどと思うなよ。
名前は大事だ、何を扱っているのか他の隊員が見ても一目でわかるようにしろ！

そうでなければ、事故を起こすぞ！　ましてや、今は爆弾を生成する関数を作っているんだ！もっと慎重にことにあたれ！いいなわかったか！

* はい！

以下のように修正しました！

```elixir
defmodule TNT do
    def create_c4(rdx, polyisobutylene, motorOil, dioctylSebacate, gasoline) do
        rdx
        polyisobutylene
        motorOil
        dioctylSebacate
        gasoline
    end
end
```

よし、それでは貴様ら、材料を全て入れて動かしてみろ！

* はい、

```elixir
TNT.create_c4({"RDX", "45.5g"}, {"ポリイソブチレン", "10.5g"}, {"モーターオイル", "0.8g"}, {"セバシン酸ジオクチル", "2.65g"},{"ガソリン", "25ml"})
{"ガソリン", "25ml"}
```

* 結果がガソリンしか出てきません！

そうだ！Elixirの関数では一番下に書かれているものが結果として返ってくる仕組みになっている。だから、今回は入力した値をそのまま返すようにしたい場合には、リストやマップ、もしくはタプルなどで１つのデータにして返す必要がある。わかったか。

それでは、今回はリストにして返すようにしてみろ！

* はい

```elixir
defmodule TNT do
    def create_c4(rdx, polyisobutylene, motorOil, dioctylSebacate, gasoline) do
        [
            rdx,
            polyisobutylene,
            motorOil,
            dioctylSebacate,
            gasoline,
        ]
    end
end
```

```elixir
TNT.create_c4({"RDX", "45.5g"},{"ポリイソブチレン", "10.5g"},{"モーターオイル", "0.8g"},{"セバシン酸ジオクチル", "2.65g"},{"ガソリン", "25ml"})
[
  {"RDX", "45.5g"},
  {"ポリイソブチレン", "10.5g"},
  {"モーターオイル", "0.8g"},
  {"セバシン酸ジオクチル", "2.65g"},
  {"ガソリン", "25ml"}
]
```
よし、いいだろう！　だが、このままでは RDX, ポリイソブチレン、モーターオイル、セバシン酸ジオクチル、ガソリン以外はそもそも受け付けないようにしたい。

そこで、引数で受け取る時にすでに RDXなどでパターンがマッチしる場合に動くように改造しろ。

```elixir
defmodule TNT do
    def create_c4({"RDX", rdx},{"ポリイソブチレン", polyisobutylene},{"モーターオイル", motorOil},{"セバシン酸ジオクチル", dioctylSebacate},{"ガソリン", gasoline}) do
        [
            rdx,
            polyisobutylene,
            motorOil,
            dioctylSebacate,
            gasoline,
        ]
    end
end
```

よし、早速動かしてみろ、そして試しにRDXをTNTにした場合も実施しろ！

```elixir
# 正しい値を入れた場合
TNT.create_c4({"RDX", "45.5g"}, {"ポリイソブチレン", "10.5g"}, {"モーターオイル", "0.8g"}, {"セバシン酸ジオクチル", "2.65g"},{"ガソリン", "25ml"})
["45.5g", "10.5g", "0.8g", "2.65g", "25ml"]

# RDXをTNTにした場合
TNT.create_c4({"TNT", "45.5g"}, {"ポリイソブチレン", "10.5g"}, {"モーターオイル", "0.8g"}, {"セバシン酸ジオクチル", "2.65g"},{"ガソリン", "25ml"})
** (FunctionClauseError) no function clause matching in TNT.create_c4/5    
    
    The following arguments were given to TNT.create_c4/5:
    
        # 1
        {"TNT", "45.5g"}
    
        # 2
        {"ポリイソブチレン", "10.5g"}
    
        # 3
        {"モーターオイル", "0.8g"}
    
        # 4
        {"セバシン酸ジオクチル", "2.65g"}
    
        # 5
        {"ガソリン", "25ml"}
    
    #cell:3saeimyrnuk5y3b6yqtsypjkn4cgjwmn:3: TNT.create_c4/5
    #cell:gblzofzf4jc635je3scjzdsgkxx2nhwu:1: (file)
```

よし、いいだろう！これで正しい成分が入ってない場合はエラーが出るようになったな。

では、貴様らにはさらに色々な技をマスターしてもらうとしよう！
しかし、この先を始めると長くなるので、今日はここまで、それでは次回 Part17でまた会おう！