Elixirを勉強し始めたときに役立つトピック

# はじめに

基本、Webサイト「[Elixir School](https://elixirschool.com)」 と 書籍「[プログラミング Elixir](https://www.amazon.co.jp/プログラミングElixir-Dave-Thomas/dp/4274219151)」を使って勉強

本記事では、
　１、勉強し始めたばかりのときに調べた用語
　２、実装時、覚えるまで手元に置いておきたい情報
　３、実装時、覚えるまで手元に置いておきたいコマンド
　４、参照URL
を記載します

すぐに不要になっちゃうレベルの内容だけど、誰かのお役に立てれば！


# １、勉強し始めたばかりのときに調べた用語

### アトム（Atoms）
名前が自身の値を表わしている定数（別言語でいうところのシンボル）

### アリティ（arity）
引数の数

### リスト
定義方法：[1, 2, 3]

### タプル（tuple）
定義方法：{1, 2, 3}
リストのようなもの。リストとの違いは以下
- 波括弧
- 各要素をメモリ上に隣接して格納
　　…補足
　　　リストは事実上の連結リストで実装されている
　　　そのため、長さを得る処理はタプルのほうが高速だが
　　　先頭に要素を追加するには、ほとんどの場合リストのほうが高速となる
- データを変更できない

### マップ
定義方法：%{key1: => val1, key2 => val2}
　…キーがアトム型のみの場合は　%{key1: val1, key2: val2} という書き方もOK
値の取得：map[key]
　…map：マップ名、key：キー名
　　キーがアトムの場合は、map.key でもOK
値の更新：%{map | key: val}
　…mapそのものが書き換わるわけではないことに注意

### アキュムレータ（accumulator、acc）
レジスタ／変数の一種
論理演算や四則演算などによるデータの入出力と結果の保持に用いる
記憶された値と別の値の間で演算が行われ、結果がまたそこに記憶される

### ビヘイビア（behavior / behaviour）
特定の要素がある条件下でどのような 振る舞い／挙動 をするかを指す

### シギル（sigil）
文字列リテラルを表現したり取り扱うための構文
チルダ（~）から始まり文字が一つそれに続く

```elixir
# 例：シギルの「~c」を使った例
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
```

### レプル（REPL、Read-eval-print loopの略）
読む・評価・表示 を繰り返す対話型評価環境のこと
Elixir開発では、IEx がそれ

### フォールトトレランス（fault tolerance）
過失許容性
システムにおいて起こりうる障害（誤作動や誤操作）に対する耐性のこと
障害が発生しても予備の系統に切り替えるなどして機能を保ち、正常に稼動させ続けることをいう
また，この耐性を向上させるため，事前対策を行おうとする設計（思想）のこと
フェイル-セーフ，フール-プルーフなどの方法がある

### OTP（Open Telecom Platformの略）
並行プログラミングのために完備された開発環境
システム開発の基盤となる Erlangの コンパイラ／ライブラリ、および、フレームワーク・デザイン原則 の総称

### GenServer
汎用サーバモジュール
Elixirによって用意されたフレームワークの一つであり、
OTPのデザイン原則の中心的なものの一つ「アプリケーションパターン」（ビヘイビア）では
共通的なタスクに対して汎用的な実装を定義しており、その一例でもある
更新された状態を伝える反復処理のたびに1つのリクエストを処理するループ


# ２、実装時、覚えるまで手元に置いておきたい情報

### Elixirでの偽
nil と false のみ

### モジュール内での定数定義
アットリビュートを使用する
例）@greeting "Hello"

### Elixirでの予約語
|予約語|用途|
|---|---|
|moduledoc|現在のモジュールにドキュメントを付ける|
|doc|関数やマクロについてのドキュメント管理|
|behaviour|OTP またはユーザが定義した振る舞い(ビヘイビア)に用いる|

### 文字列と文字リスト

文字列
ダブルクオートで生成される
バイナリで表現されているコードポイントを UTF-8 でエンコードしている

```elixir
# 例
iex> "テスト"
"テスト"
iex> "テスト" <> <<0>>
<<227, 131, 134, 227, 130, 185, 227, 131, 136, 0>>
```

文字リスト
シングルクオートで生成される
バイナリで表現されているコードポイント

```elixir
# 例
iex> 'テスト'
[12486, 12473, 12488]
```

通常は、文字列を使う
文字リストは、一部の Erlang モジュールが必要としているためサポートされている形

### コメント記載方法

① インラインドキュメント

```elixir:example.ex
# コメント
```

② モジュールレベルのドキュメント
　→defmodule 宣言の直後に記載

```elixir:example.ex
defmodule Greeter do
  @moduledoc """
  ...コメント...
  """
```

③ 関数レベルのドキュメント
　→ 注釈を付けたい関数の直前に記載

```elixir:example.ex
@doc """
...コメント...

## パラメータ
  - name: 人名を表現する文字
## 例
  iex> Greeter.hello("Sean")
  "Hello, Sean"
"""
@spec hello(String.t()) :: String.t()
def hello(name) do
  "Hello, " <> name
end
```

補足事項
* 関数に言及する場合は、「\`hello/1\`」のようにバッククォートを使用すること
* なるべくコード例も記載することで、自動テスト（[doctest](https://hexdocs.pm/ex_unit/ExUnit.DocTest.html)）を生成すること
* コメント更新時は、コマンド「mix docs」を実行することも忘れずに
* ドキュメントを綺麗なHTML表記に変換するため、依存関係（mix.exsのdeps内）に以下を定義しておくとよい
　定義追加後は、コマンド「mix deps.get」を実行することも忘れずに

```elixir:mix.exs
{:earmark, "~> 0.1", only: :dev},
{:ex_doc, "~> 0.11", only: :dev}
```

### Mixタスクの説明文記載
Mixタスクの .ex 内で「@shortdoc "XXX"」を記載する
ここで記載した内容は、ターミナルで「mix help」を実行時に表示される

### プロジェクト構成

```
.
├── _build                  #ビルドによる成果物
├── config                  #設定ファイル
│   └── config.exs
├── deps                    #依存関係
│   └── XXX
├── doc                     #ドキュメント
│   └── XXX
├── lib                     #アプリケーションのソースコード
│   └── example.ex
├── mix.exs                 #プロジェクトの定義（プロジェクト名、バージョン、依存関係など）
├── README.md
└── test                    #テストコード
    ├── example_test.exs
    └── test_helper.exs
```

# ３、実装時、覚えるまで手元に置いておきたいコマンド

### 実行終了方法
iexの終了時は、CTRL/C → a（abort）
打ち間違えなどでのコマンド実行中断時は、「#iex:break」

### ヘルプ呼び出し
コマンド「h」
例）h Enum

補足事項
* コマンド型、ソースコード在り処 や 関連モジュールなどの情報を見る場合は、コマンド「i」を使う
* mix について知りたい場合は、iexの外部で「mix help」を実行

### 画面クリア
「clear」

### 入出力
「IO.puts "XXX"」
例）
IO.puts "hoge"
IO.puts "#{foo}"

### プロジェクトの作成
「mix new XXXX」　XXXX：プロジェクト名

### プロジェクトの実行
プロジェクト直下のディレクトリで「iex -S mix」を実行

### コンパイル
「iex -S mix」でプロジェクト実行時、必要に応じてコードの変更をコンパイルしてくれるが
明示的にコンパイルしたい場合は「mix compile」を実行
また、モジュール単位など部分的にコンパイルしたい場合は「r XXXX」(XXXX：モジュール名) で実行可能

### プロジェクトの実行環境確認／変更
mixは、以下3つの環境で動作するようになっている
　- :dev - 開発時に用いられる環境
　- :test - mix testで用いられる環境
　- :prod - アプリケーション製品出荷時に用いられる環境

現在の実行環境は「Mix.env」で取得することができる
環境を変更するには、MIX_ENV環境変数を変更する
例）$ MIX_ENV=prod mix compile

### プロジェクトへの依存関係の取り込み
mix.exsのdeps内に定義した依存関係を取り込むためには「mix deps.get」を実行

### コメント記載からのドキュメント作成／更新
「mix docs」
実行後、ドキュメント（ExDoc）は、ディレクトリ：doc/ 内に出来上がる

### テストの実行
「mix test」

### 文字列のバイナリ表記
1バイトずつカンマ区切りで<<...>>で囲む

```elixir
# 例
iex> <<104, 101, 108, 108, 111>>
"hello"
```

バイト列の結合は<>演算子を使う

```elixir
# 例
iex> <<104, 101, 108>> <> <<108, 111>>
"hello"
```

文字列のバイナリ表現を確認するには、NULL文字<<0>>を結合
　…<<0>> を追加することで文字列として不正となり、バイナリで表示される
　　文字コードを確認する時などに便利

```elixir
# 例
iex> "hello" <> <<0>>
<<104, 101, 108, 108, 111, 0>>
```

### エラーハンドリング
try/rescue を使う

```elixir
iex> try do
...>   # 通常処理
...> rescue
...>   # エラー処理。複数エラーにマッチさせることができる
...>   e in RuntimeError -> IO.puts("An error occurred: " <> e.message)
...>   e in File.Error -> IO.puts("unable to read source file")
...> after
...>   # エラー有無に関わらず実行したい処理
...>   IO.puts "The end!"
...> end
```

throw/catch もあるが、Elixir コードでこれらを使うのは非常に稀

### プロジェクトの終了
終了する場合は「exit("XXX")」を実行

### 実行ファイルのビルド／実行
以下の対応を入れることで、コマンドラインから実行できるようになる

[実行ファイルの準備]
Mixfile で以下２点を修正する
①escript オプションを追加

```elixir:mix.exs
def project do
[
  app: :example,
  ・・中略・・,
  escript: escript()  #ココを追加
]
end
```

②「main_module」 を指定

```elixir:mix.exs
defp escript do
  [main_module: XXXX]    #XXXX：実行ファイル
end
```

[ビルド]
「mix escript.build」を実行

[実行]
「./XXXX YYYY」を実行　　XXXX：アプリ名、YYYY：引数


# ４、参照URL

* Elixir School
https://elixirschool.com

* 書籍「プログラミング Elixir」
https://www.amazon.co.jp/プログラミングElixir-Dave-Thomas/dp/4274219151

* Elixir公式サイト
https://elixir-lang.org

* チュートリアル
http://elixir-ja.sena-net.works/getting_started/1.html

* Elixir Style Guide
https://github.com/christopheradams/elixir_style_guide

* ExDoc
https://github.com/elixir-lang/ex_doc