Elixirのチートシートを作ろう #19 シギルその２


# 1. OverView

Sigilsの続き。本日は12/25ですねー。
これにて、アドベントカレンダーとしてのチートシート作りは終わりたいと思います。
いや、面白いのでどんどん作りますけどね。書き直したいところも出てきました。

昨日も書きましたが、シジル、ややっこしいけど理にかなってて、面白い仕組みですね。


# 2. まずは解説
## 2.1 文字列

先日の文字のリストと似てますね。~s 及び ~S シギルは文字列データを生成するのに使われます。
sとSの違いは、エスケープシーケンスを処理するか、ですね。

```
iex(39)> ~s/welcome to elixir #{String.downcase "SCHOOL"}/
"welcome to elixir school"
iex(40)> ~S/welcome to elixir #{String.downcase "SCHOOL"}/
"welcome to elixir \#{String.downcase \"SCHOOL\"}"
```

~Sの方は、#{}の中が評価されず、そのまま表示されております。

```
iex(41)> is_binary(~S/welcome to elixir #{String.downcase "SCHOOL"}/)
true
```
戻り値も文字列ですね。

## 2.2 単語のリスト

さて、スペースで区切られた文字列を、listで返してくれるシギル、それが~wと~Wです。
wとWの違いは、エスケープシーケンスを処理するか、ですね。

```
iex(47)> ~w/i love #{'e'}lixir school/
["i", "love", "elixir", "school"]
iex(48)> ~W/i love #{'e'}lixir school/
["i", "love", "\#{'e'}lixir", "school"]
```

区切り文字はスペースから変更できなさそうですね。


## 2.3 NaiveDateTime

これ、日付をやる際に、飛ばします。
迂闊に例を出すと「 NaiveDateTime 構造体を直接作ることは避けるべきです」と書いてあるので、ちょっと警戒しております。

# 2.4 シギルを作る。

さて、シギルを作ってみましょう。
まー、オレオレシギルを作ってもダメでしょうが、ライブラリやフレームワークで見かけるかも知れません。
なので、今までの総合で、しっかりやりましょう。

https://elixirschool.com/ja/lessons/basics/sigils#%E3%82%B7%E3%82%AE%E3%83%AB%E3%82%92%E4%BD%9C%E3%82%8B-6

まずは、ここのサンプル
```
defmodule MySigils do
  def sigil_u(string, []), do: String.upcase(string)
end
```

sigil_uを格納する為に、MySigilsと言うモジュールを定義しております。
sigil_uと言う関数を定義してますね。
関数本体が1行で済むなら、 do: を使ってより短くすることが出来るそうですよ！ググりました！自分のチートシート出て来たｗ

さて、次
```
iex(6)> import MySigils
MySigils
iex(7)> ~u/elixir school/
"ELIXIR SCHOOL"
```

importで、先ほど定義したモジュールをimportしております。
そして、見事、オリジナルシジルuで、~u/elixir school/が評価されました。

…待てよ？
# 2.5 シギルを作る…の蛇足

defmodule MySigilsもわかる、import MySigilsもわからんでもない。
では？それだけ？

どうやら、sigilは、~に続く一文字の関数を呼び出しているみたいです。

今回はsigil_uでしたね。では、試しに、存在しないシジルkでやってみましょう。
```
iex(8)> ~k/elixir school/
error: undefined function sigil_k/2 (there is no such import)
  iex:8

** (CompileError) cannot compile code (errors have been logged)
```

なので、import MySigilsして、sigil_u/2が呼びさせる様にしてやった様です。

え？/2？そういや、正規表現の時に、そう言えば後ろにオプション付けてましたね。
re = ~r/elixir/i <--このiね。

となると、やってみよう。
```
defmodule MySigils do
  def sigil_u(string, opt), do: String.upcase(~s/#{string} with #{opt}/)
end
```

インポートはしてくださいね。念の為
```
iex(2)> import MySigils
MySigils
iex(6)>  ~u/elixir school/opt
"ELIXIR SCHOOL WITH OPT"
```
をー、シギルのデリミタの後ろのオプションもちゃんと読んでますなー。

さて、こんなところで、ちょっとはmoduleとかimportの実例を示せたでしょうか？
そう思っていただけると、蛇足にした甲斐がありますw

|シジルの種類|説明|例|
|:--------|:----------------------------------------|:------------------------------------------------------------------------|
|~c 及び ~C|シギルはそれぞれ文字のリストを生成します。<br>~Cは中のエスケープシーケンスを評価しません|iex(14)> ~c/2 + 7 = #{2 + 7}/<br>~c"2 + 7 = 9"<br>iex(15)> ~C/2 + 7 = #{2 + 7}/<br>~c"2 + 7 = \#{2 + 7}"<br>|
|~r 及び ~R|~r 及び ~R シギルはそれぞれ正規表現を生成します。rはエスケープシーケンスを解釈しますが、Rがエスケープシーケンスを解釈しません|iex(31)> re = \~r/[Ee]lixir/<br>iex(32)> "Elixir" =~ re<br>true<br>|
|~s 及び ~S|シギルはそれぞれ文字列を生成します。<br>~sは中のエスケープシーケンスを評価しません|iex(39)> ~s/welcome to elixir #{String.downcase "SCHOOL"}/<br>"welcome to elixir school"<br>iex(40)> ~S/welcome to elixir #{String.downcase "SCHOOL"}/<br>"welcome to elixir \#{String.downcase \"SCHOOL\"}"|
|~w 及び ~w|スペースで区切られた文字列を、listで返します。~Wは中のエスケープシーケンスを評価しません|iex(47)> ~w/i love #{'e'}lixir school/<br>["i", "love", "elixir", "school"]<br>iex(48)> ~W/i love #{'e'}lixir school/<br>["i", "love", "\#{'e'}lixir", "school"]|