LoginSignup
11
10

More than 5 years have passed since last update.

Sigil大好き!一番好きな機能です。

Last updated at Posted at 2013-12-13

Elixirには、Rubyなどの言語に見られるような %w(...) という記法が存在する。Elixirのドキュメントではそれを「Sigil」と呼んでいる。

%w(foo bar 123)
#=> ["foo", "bar", "123"]

ドキュメントにある通り以下の4つがデフォルトで定義済み。

  • %c and %C - Returns a char list;
  • %r and %R - Returns a regular expression;
  • %s and %S - Returns a string;
  • %w and %W - Returns a list of "words" split by whitespace;

また、Rubyの同様の表記と違い、接尾辞を指定できる。「modifier」と呼ばれる。無いものを指定すると例外。

%w(foo bar 123)a
#=> [:foo, :bar, :"123"]
%w(foo bar 123)z
# ** (ArgumentError) modifier must be one of: s, a, c
#    /private/tmp/elixir-s8oh/elixir-0.11.2/lib/elixir/lib/kernel.ex:3624: Kernel.split_words/2
#    iex:13: Kernel.sigil_w/2

このSigil記法、最終的にはsigil_*という名前の関数またはマクロが呼ばれることになるので、

%p()
# ** (RuntimeError) undefined function: sigil_p/2

このような名前の関数もしくはマクロを定義してあげると、独自のSigilを定義できる。

defmodule MySigil do
  def sigil_p(string, []) do
    IO.inspect(string)
  end
end

import MySigil
%p(Hello!)
#=> "Hello!"

この際sigil_p/2になるように定義すること。2番目の引数にはもちろんmodifierが入ってくる。

以下はSigilの内容のmd5ハッシュを出すサンプル。

defmodule Crypto do
  def to_md5(str) do
    Enum.join(
      Enum.map(
        bitstring_to_list(:crypto.hash :md5, str),
        fn(x) -> String.rjust(integer_to_binary(x, 16), 2, ?0) end
      )
    )
  end

  def sigil_m(string, []) do
    to_md5(string)
  end
end

import Crypto

%m'''
foo
bar
baz
'''
#=> "268A5059001855FEF30B4F95F82044ED"

Enjoy Sigiling!

次回はさっちゃんさんです!!

11
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
10