どうも、靖宗です。
この章はSigil。まったく聞いたこともないので辞書で調べてみるとシジルまたはシギル(英: sigil、羅: sigillum)は主に西洋魔術で使われる図形、記号、紋章、線形である。
。
とうとう魔術まで出てきました・・・
- Regular expressions(正規表現)
- Strings, char lists, and word lists sigils
- Interpolation and escaping in sigils
- Custom sigils
なんか文字列拡張しようぜ!みたいな雰囲気の文章が書かれていますが、英語がそこまで得意じゃない自分はコードで読み解いていきます。
クソザコ英語能力で分かるのは~
で始まり、なんか区切り文字があるのがsigil
だよ!と書いてある事ぐらいです。
それでは進んでいきましょう。
Regular expressions(正規表現)
まぁプログラミング言語ならありますよね、という感じの正規表現。
なじみ深い感じで~r
で表されるようです。
# A regular expression that matches strings which contain "foo" or "bar": iex> regex = ~r/foo|bar/ ~r/foo|bar/ iex> "foo" =~ regex true iex> "bat" =~ regex false
小文字大文字判定などのオプションの付け方はPerlとコンパチだそうです。
必要に応じて調べれば良さそう。
iex> "HELLO" =~ ~r/hello/ false iex> "HELLO" =~ ~r/hello/i true
今は/
を区切り文字として使ってますが、Elixirでは以下の8つが使用できるそうで。
~r/hello/ ~r|hello| ~r"hello" ~r'hello' ~r(hello) ~r[hello] ~r{hello} ~r<hello>
なんなら統一してくれた方が楽な気がするんですが・・・
一応パターン次第ではエスケープ文字が冗長になる(~r/^https?:\/\//
の区切り文字を変えれば~r(^https?://)
と表現できるのでスッキリ!)からって理由だそうですが、しっかりエスケープした方が間違いが少なくなるような。
何はともあれすすみませう
Strings, char lists, and word lists sigils
正規表現の他にもいろいろなsigilが。
Strings
~s
でダブルクォーテーションの文字列(一般的な文字列)が生成できるとのこと。
iex> ~s(this is a string with "double" quotes, not 'single' ones) "this is a string with \"double\" quotes, not 'single' ones"
ダブルクォーテーションが勝手にエスケープされてたりと、これは有用かもしれません。(ケースバイケースだとは思います)
Char lists
こちらはシングルクォートの方ですね。最初が~c
であること以外は特に変わりません。
iex> ~c(this is a char list containing 'single quotes') 'this is a char list containing \'single quotes\''
こちらもきっちりシングルクォートはエスケープされております。
Word lists
こちらは文字列のリストを生成するためのsigilだそうです。
空白で区切った文字がリストとなるようです。これは~w
です。
iex> ~w(foo bar bat) ["foo", "bar", "bat"]
Word listsのsigilにはオプションが利用でき、c
でChar listsへ、a
でアトムへ変換するようです。文字列へは何も指定しなくて大丈夫ですが、一応s
のオプションがあるようです。
iex> ~w(foo bar bat)a [:foo, :bar, :bat]
Interpolation and escaping in sigils
sigilは大文字と小文字の場合で挙動が違うようです。
小文字の場合はinterpolation(#{}
で文字列中で変換したりするやつ)はいつも通り計算されるようですが、大文字であればこの補間は行われないようです。
iex(68)> ~s(String with escape codes \x26 #{"inter" <> "polation"}) "String with escape codes & interpolation" iex(69)> ~S(String with escape codes \x26 #{"inter" <> "polation"}) "String with escape codes \\x26 \#{\"inter\" <> \"polation\"}"
サンプルはなぜか大文字と小文字で文章が変わってますが、比較するなら同じものを実行するべきだと思います(╬´◓ω◔`╬)
大文字だとエスケープシーケンスの文字も自動でエスケープが入るようです。
iex(74)> ~s(\a) "\a" iex(75)> ~S(\a) "\\a"
一応sigilでは`
や"
はエスケープできるけど区切り文字変えようね!とは書いてます。
郷に入っては郷に従えか・・・
ちなみに余談ですがMarkdownでバックォートのエスケープが分からずぐぐりました。↑のバッククォートは
`` ` ``
と書かれてます。
sigilは関数の属性のところで出てきた@doc
に書くような3つの(ダブル|シングル)クォートに対応しているようです。
iex> ~s""" ...> this is ...> a heredoc string ...> """
これはそのまんま、@doc
などに活用されるようです。
@doc """ Converts double-quotes to single-quotes. ## Examples iex> convert("\\\"foo\\\"") "'foo'" """ def convert(...)
これではエラーがでるので
@doc ~S""" Converts double-quotes to single-quotes. ## Examples iex> convert("\"foo\"") "'foo'" """ def convert(...)
こう書くと。確かにこちらの方が分かりやすい。
Custom sigils
Elixirの哲学?目標?の一部に拡張性があるらしいんですが、sigilもカスタマイズできるようになっているそうです。
正規表現のsigilがsigil_r
という関数で表現できるようで
iex> sigil_r(<<"foo">>, 'i') ~r"foo"i
これと同じ様にsigil_{もじ}
という関数を定義すればsigilとして利用できるようです。
サンプルを見ます。
iex> defmodule MySigils do ...> def sigil_i(string, []), do: String.to_integer(string) ...> def sigil_i(string, [?n]), do: -String.to_integer(string) ...> end iex> import MySigils iex> ~i(13) 13 iex> ~i(42)n -42
MySigils
モジュールではsigil_i
を定義してるだけですが、~i
が利用できるようになっています。
区切り文字なども特に定義の中には書かれていませんが、sigilと同様の挙動を取っている所をみるとsigilのカスタマイズとして認識されているようです。