1. OverView
Sigils, シジルをやって、アドベントカレンダーをしめくりたいと思います。
はい、mixは、来年に期待でw
さて、シジル、Elixir Schoolを見てみましょう。
Elixirには文字列リテラルを表現したり取り扱うための別の構文があります。
シギル(sigil)はチルダ ~ から始まり文字が一つそれに続きます。
Elixirのコアには予め組み込まれたシギルがありますが、
それだけではなく言語を拡張したい場合には独自のシギルを作ることもできます。
最初に一行に注目、文字列リテラルを表現したり取り扱うための構文だそうです。
しかし、実際に使ってみると、様々な表現が出来て、こう表現していいのか?とすら思います。
では、始めましょう。
2. まずは解説
2.1 まずは、シジルの使い方
俺、吟遊詩人になろうかな、異世界を回って、SystemVのすばらしさを語って回るんだ…落ち着こうか?
先に例行きます!ああ、これね|となるでしょう。
iex(1)> name = "Alice"
"Alice"
iex(2)> ~s(Hello, #{name})
"Hello, Alice!"
上の、 ~s{Hello, #{name}}がシジル、文中に#{}に囲まれた変数nameを、置換して、文字列にしてくれてますね。
えーと、C言語で書くとprintf("%s", name);みたいになるんでしょうか?
では、文法
~[文字]{}
上の文字がシジルの種類、その後の{}で囲まれた文字列が戻り値となります。
この{}がデリミタと呼ばれる「区切り」なのですが、さぁ、お立合い。
デリミタが、こんなにあります。
デリミタの種類 | 説明 | 例 |
---|---|---|
<...> | カギ括弧のペア | ~s |
{...} | 中括弧のペア | ~s{Hello, #{name}} |
[...] | 大括弧のペア | ~s[Hello, #{name}] |
(...) | 小括弧のペア | ~s(Hello, #{name}) |
|...| | パイプ記号のペア | ~s|Hello, #{name}| |
/.../ | スラッシュのペア | ~s/Hello, #{name}/ |
"..." | ダブルクォートのペア | ~s"Hello, #{name}" |
'...' | シングルクォートのペア | ~s'Hello, #{name}' |
上の例、~s(Hello, #{name})が、どのデリミタでも動くんです。
iex(6)> ~s<Hello, #{name}>
"Hello, Alice"
iex(7)> ~s{Hello, #{name}}
"Hello, Alice"
iex(8)> ~s[Hello, #{name}]
"Hello, Alice"
iex(9)> ~s(Hello, #{name})
"Hello, Alice"
iex(10)> ~s|Hello, #{name}|
"Hello, Alice"
iex(11)> ~s/Hello, #{name}/
"Hello, Alice"
iex(12)> ~s"Hello, #{name}"
"Hello, Alice"
iex(13)> ~s'Hello, #{name}'
"Hello, Alice"
冗長で嫌だなぁ、と思った方も多いでしょうが、シジルって、取り扱える文字列の表現、型が非常に多く、
戻り値が文字列ですらないので、これくらいじゃないと、何か書くたびにエスケープシーケンス文字で
死ぬ羽目になると思います。
2.1 文字のリスト
~c 及び ~C シギルはそれぞれ文字のリストを生成します。
この分、引っかかりますね?「文字のリスト」を作成します…リスト型なんですわ。
~cは、#{}で囲まれた式を評価し、埋め込んでくれます。
~Cは、中の式を評価しません。
iex(14)> ~c/2 + 7 = #{2 + 7}/
~c"2 + 7 = 9"
iex(15)> ~C/2 + 7 = #{2 + 7}/
~c"2 + 7 = \#{2 + 7}"
iex(16)> is_list(~C/2 + 7 = #{2 + 7}/)
true
2.2 正規表現
~r 及び ~R シギルはそれぞれ正規表現を生成します。正規表現は動的にも Regex 関数内で使うためにも生成できます。
いきなり大物がぶっ込まれました、正規表現です。
うん、僕の10年分くらいのアドベントカレンダーになっちゃうので、まずは、例を見ましょう。
例の前に、比較の演算子が=~になってますが、これ、正規表現のパターンマッチングが出来る演算子だそうです。
iex(26)> re = ~r/elixir/
~r/elixir/
iex(27)> "elixir" =~ re
true
iex(28)> "Elixir" =~ re
false
では、正規表現をちょっとだけ複雑にしてみましょう
iex(31)> re = ~r/[Ee]lixir/
~r/[Ee]lixir/
iex(32)> "Elixir" =~ re
true
正規表現について、せっかくElixir Schoolで様々な例が出ているので、張っときますね。
ElixirはPerl Compatible Regular Expressions (Perl互換正規表現式, PCRE)をサポートしているのでシギルの末尾に i を追加することで大文字・小文字の区別をしないように指定できます。
PCREの正規表現が使えるそうです。うん、僕、AWKの奴しか知らない。(ほんとにSEか?お前?)
今度勉強しとくわ。
以下の例、末尾に i を追加することで大文字・小文字の区別をしないようになってます。
iex(33)> re = ~r/elixir/i
~r/elixir/i
iex(34)> "Elixir" =~ re
true
さて、本日分はここでおしまい。
え?アドベントカレンダーの記事にするために、分割したろって?
いやいや、意外と次にやること多いのよ。
3. 本日のチートシート
シジルの種類 | 説明 | 例 |
---|---|---|
~c 及び ~C | シギルはそれぞれ文字のリストを生成します。 ~Cは中の式を評価しません |
iex(14)> ~c/2 + 7 = #{2 + 7}/ ~c"2 + 7 = 9" iex(15)> ~C/2 + 7 = #{2 + 7}/ ~c"2 + 7 = #{2 + 7}" |
~r 及び ~R | ~r 及び ~R シギルはそれぞれ正規表現を生成します。rはエスケープシーケンスを解釈しますが、Rがエスケープシーケンスを解釈しません | iex(31)> re = ~r/[Ee]lixir/ iex(32)> "Elixir" =~ re true |
シジルに使えるデリミタの種類
デリミタの種類 | 説明 | 例 |
---|---|---|
<...> | カギ括弧のペア | ~s |
{...} | 中括弧のペア | ~s{Hello, #{name}} |
[...] | 大括弧のペア | ~s[Hello, #{name}] |
(...) | 小括弧のペア | ~s(Hello, #{name}) |
|...| | パイプ記号のペア | ~s|Hello, #{name}| |
/.../ | スラッシュのペア | ~s/Hello, #{name}/ |
"..." | ダブルクォートのペア | ~s"Hello, #{name}" |
'...' | シングルクォートのペア | ~s'Hello, #{name}' |