読者です 読者をやめる 読者になる 読者になる

もやもやエンジニア

IT系のネタで思ったことや技術系のネタを備忘録的に綴っていきます。フロント率高め。

Elixir 入門 その17 - Sigils

  • ~ で始まるテキストをSigilといい、文字列を扱うための仕組みを提供する。
  • delimiter sigil delimiter modifier の形式。r/hogehoge/i みたいな形。

Regular expressions

  • ~rはよく使われるSigilで正規表現を作成するために使う
  • 正規表現Perl-compatible regular expressions が組み込まれている
# fooかbarだったらtrueを返す正規表現を作成
iex> regex = ~r/foo|bar/
~r/foo|bar/

iex> "foo" =~ regex
true

iex> "bat" =~ regex
false

Strings, char lists and words sigils

Strings

  • ~s は文字列を生成するためのSigil。"で囲むのと同じ意味合いだけど、こちらは文字列内に文字列内に"が含まれている場合でもエスケープしないでstringを作成できる
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

  • ~w はスペース区切りの文字列をSplitしてListを返すSigil
  • modifierとしてc、s、a を受け入れることができて、指定すると分割した上でmodifierに応じた型でListに詰め込まれて変換される
iex> ~w(foo bar bat)
["foo", "bar", "bat"]

# aはatomになる
iex> ~w(foo bar bat)a
[:foo, :bar, :bat]

Interpolation and escaping in sigils

  • sigilは小文字と大文字で動きが異なる。~s~Sの違いを見てみる
# こちらは中の式やコードが展開されて文字列に変換される
iex> ~s(String with escape codes \x26 #{"inter" <> "polation"})
"String with escape codes & interpolation"

# こちらは中の式はそのまま出力される
iex> ~S(String with escape codes \x26 #{"inter" <> "polation"})
"String with escape codes \\x26 \#{\"inter\" <> \"polation\"}"
  • サポートしているエスケープ文字

  • \" – double quote

  • \' – single quote
  • \ – single backslash
  • \a – bell/alert
  • \b – backspace
  • \d - delete
  • \e - escape
  • \f - form feed
  • \n – newline
  • \r – carriage return
  • \s – space
  • \t – tab
  • \v – vertical tab
  • \0 - null byte
  • \xDD - character with hexadecimal representation DD (e.g., \x13)
  • \x{D...} - character with hexadecimal representation with one or more hexadecimal digits (e.g., \x{abc13})

  • 関数のドキュメントを書くときなどは ~Sを使うと便利な場合がある。

# 例えば使い方のコメントで下のように書くところを
 iex> convert("\\\"foo\\\"")

# ~Sでくるめばこう書ける
 iex> convert("\"foo\"")

Custom sigils

  • Sigilは自作することもできる
  • 作り方は sigil_{identifier}/2 で関数を定義する。引数のところは stringとオプションを受け取るList
  • Macroを使って動的にSigilを作成することもできるらしい。
# 整数を返す `~i` という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