スポンサーリンク

2016年2月7日

ElixirSchoolに入校したメモ(1日目)

Goal

  • 3日間でElixirを再速習して何かを作る
  • 忘れてしまったElixirを力を取り戻すためにElixir Schoolを卒業する
  • Elixir Schoolの内容でメモ(備忘録)を作る

Dev-Environment

OS: Windows8.1
Erlang: Eshell V7.2.1, OTP-Version 18.1
Elixir: v1.2.0

Wait a minute

お久しぶりです。久々の投稿になります。
色々忙しかったり、固形物が食べれなくなったり、夜寝れなくなったりしましたが、何とか生きています!
生きているって素晴らしい…(´;ω;`)ブワッ
閑話休題…
久々の投稿ですっかりElixirを忘れてしまったので、Elixirの覚え直しから始めます。
本当ならPhoenix Tutorialの更新などを行いたかったのですが、
残念ながら今の私のレベルでは数か月前のソースコードが分からない状態です。
そのため、リハビリがてらの備忘録です。
俺得なだけの内容です。

Index

Elixir Schoolに入校したメモ(1日目)
|> コマンドまとめ
|> 基本の型まとめ
|> 演算子まとめ
|> コレクション
|> パターンマッチ
|> 条件分岐
|> 関数
|> モジュール定義
|> ドキュメントの書き方
|> ExUnit
|> シギル(Sigil)

コマンドまとめ

  • elixir: スクリプトの実行(.exs)
  • elixirc: コンパイル(.ex)
  • iex: 対話型シェル
  • mix: プロジェクト管理ツール(CLI)
その他、よく使うコマンドについて。
  • mixのヘルプ
> mix help
mix                   # Runs the default task (current: "mix run")
...
iex -S mix            # Starts IEx and run the default task
  • プロジェクトの作成
> mix new fast_relearning
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/fast_relearning.ex
* creating test
* creating test/test_helper.exs
* creating test/fast_relearning_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd fast_relearning
    mix test

Run "mix help" for more commands.
  • テストの実行(上記で作成した”fast_relearning”プロジェクト内で実行)
> mix test
Compiled lib/fast_relearning.ex
Generated fast_relearning app
Consolidated Collectable
Consolidated List.Chars
Consolidated String.Chars
Consolidated Enumerable
Consolidated IEx.Info
Consolidated Inspect
.

Finished in 0.06 seconds (0.05s on load, 0.01s on tests)
1 test, 0 failures

Randomized with seed 864000
  • iexの起動
> iex
Eshell V7.2.1  (abort with ^G)
Interactive Elixir (1.2.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
  • iexをライブラリを取り込んで実行(上記で作成した”fast_relearning”プロジェクト内で実行)
> iex -S mix
Eshell V7.2.1  (abort with ^G)
Interactive Elixir (1.2.0) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)>
  • プロジェクト外で実行した結果(つまりプロジェクトが必要)
> iex -S mix
Eshell V7.2.1  (abort with ^G)
** (Mix) Could not find a Mix.Project, please ensure a mix.exs file is available
  • beamファイルの実行
> elixir -e モジュール名.関数名
他にも色々とあるが、詳しくはヘルプを参照。

基本の型まとめ

  • 整数
iex> 255
255
iex> 0
0
  • 16進数
iex> 0xff
255
iex> 0x00
  • 2進数
iex> 0b11111111
255
iex> 0b00000000
0
  • 8進数
iex> 0o644
420
  • 小数(eがあるのは64bit小数)
iex> 3.14
3.14
iex> 1.0e-10
1.0e-10
  • 真偽値(Boolean)
iex> true
true
iex> false
false
  • アトム(Atom)
iex> :foo
:foo
iex> :bar
:bar
Atomの:trueはBooleanのtureでもあり、
Atomの:falseはBooleanのfalseでもある。
iex> :true == true
true
iex> is_atom(true)
true
iex> is_boolean(:true)
true
iex> is_atom(false)
true
iex> is_boolean(:false)
true
  • 文字列
iex> "hello"
"hello"
iex> "foo
...> bar"
"foo\nbar"
iex> "foo\nbar"
"foo\nbar"

演算子まとめ

  • 四則演算
iex> 2 + 2
4
iex> 2 - 1
1
iex> 2 * 5
10
iex> 10 / 5
2.0
  • 割り算の関数
iex> div(10, 5)
2
iex> rem(10, 3)
1
  • ||、&&、!論理演算
iex> 0 || true
0
iex> true || 0
true
iex> 0 || false
0
iex> false || 0
0
iex> 0 || nil
0
iex> nil || 0
0

iex> 0 && true
true
iex> 0 && nil
nil

iex> !0
false
iex> !false
true
  • and、or、not(最初の真偽値がtrueかfalse)
iex> 0 and true
** (ArgumentError) argument error: 0

iex> true and 0
0
iex> false or true
true
iex> not false
true
  • 比較演算子(==、!=、===、!==、<=、>=、<、>)
iex> 1 > 2
false
iex> 1 < 2
true
iex> 1 == 2
false
iex> 1 != 2
true
iex> 2 === 2.0
false

Note:

小数の比較について。
===、!==は、少数を厳密に比較したい時に使う。
Elixirのソート順について。
number < atom < reference < functions < port < pid < tuple < maps < list < bitstring
  • 文字列の結合
iex> name = "hoge"
"hoge"
iex> "Hello #{name}"
"Hello hoge"
iex> "Hello " <> name
"Hello hoge"

コレクション

  • List
iex> [1, :atom, "eifie"]
[1, :atom, "eifie"]
iex> [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> [h|t] = [1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
iex> h
1
iex> t
[2, 3, 4, 5]
iex> [1, 2, 3, 4, 5] ++ [6, 7]
[1, 2, 3, 4, 5, 6, 7]
iex> [1, 2, 3, 4, 5] -- [3, 6]
[1, 2, 4, 5]
  • Tuple
iex> {1, :atom, "eifie"}
{1, :atom, "eifie"}
iex> {1, 2, 3, 4, 5}
{1, 2, 3, 4, 5}

Note:

ElixirのASTもTupleで構成されている。
マクロの話になるので興味があれば調べる。
  • Keyword list
iex> [foo: "bar", hello: :world]
[foo: "bar", hello: :world]
iex> [foo: "bar", hello: :world, foo: "bar"]
[foo: "bar", hello: :world, foo: "bar"]

Note:

要素はユニークではないため同じ要素が入れられる。
  • Map
iex> %{:foo => "bar", :hello => "world", "1" => "2"}
%{:foo => "bar", :hello => "world", "1" => "2"}
iex> %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> map = %{foo: "bar", hello: "world"}
%{foo: "bar", hello: "world"}
iex> map[:foo]
"bar"

iex> map == %{foo: "bar", hello: "world"}
true
iex> map == %{foo: "bar", hello: "bar"}
false

iex> value = :bar
:bar
iex> %{foo: value}
%{foo: :bar}
iex> key = :foo
:foo
iex> %{key => :bar}
%{foo: :bar}

Note:

同じ値を入れた場合、以下のようになる。

iex> %{foo: "bar", hello: "world", foo: "bar"}
%{foo: "bar", hello: "world"}
v1.2から変数をMapのキーに使えるようになった。

Note:

コレクションとEnumについて。
コレクションはEnumの関数で扱える。
色々な処理の仕方に対応しているので、実際に使うときにEnumのドキュメントを見ればいい。
サンプルとしてEnumのeach/2関数でListとMapを使ってみる。

Example:

iex> Enum.each([1, 2, 3, 4, 5], fn(e) -> IO.puts(e) end)
1
2
3
4
5
:ok

iex> Enum.each(%{foo: "bar", hello: "bar"}, fn({k, v}) -> IO.inspect("key: #{k}, value: #{v}") end)
"key: foo, value: bar"
"key: hello, value: bar"
:ok

パターンマッチ

  • マッチ演算子
iex> x = 1
1
iex> 1 = x
1
iex> 2 = x
** (MatchError) no match of right hand side value: 1

iex> list = [1, 2, 3]
[1, 2, 3]
iex> [1, 2, 3] = list
[1, 2, 3]
iex> [] = list
** (MatchError) no match of right hand side value: [1, 2, 3]

iex> [1|t] = list
[1, 2, 3]
iex> t
[2, 3]
iex> [2|_] = list
** (MatchError) no match of right hand side value: [1, 2, 3]

iex> [2|_] = t
[2, 3]

iex> {:ok, value} = {:ok, "Successful"}
{:ok, "Successful"}
iex> value
"Successful"
iex> {:ok, value} = {:error}
** (MatchError) no match of right hand side value: {:error}
  • ピン演算子
iex> x = 1
1
iex> ^x = 2
** (MatchError) no match of right hand side value: 2

iex> {x, ^x} = {2, 1}
{2, 1}
iex> x
2

iex> key = "hello"
"hello"
iex> %{^key => value} = %{"hello" => :world}
%{"hello" => :world}
iex> value
:world
iex> key
"hello"
iex> %{^key => value} = %{:hello => :world}
** (MatchError) no match of right hand side value: %{hello: :world}

iex> greeting = "Hello"
"Hello"
iex> greet = fn
...>   (^greeting, name) -> "Hi #{name}"
...>   (greeting, name) -> "#{greeting}, #{name}"
...> end
#Function<12.54118792/2 in :erl_eval.expr/5>
iex> greet.("Hello", "hoge")
"Hi hoge"
iex> greet.("World", "hoge")
"World, hoge"

Note:

ピン演算子は再束縛しないようにできる。
v1.2からMapのキーでもピン演算子を利用できるようになった。

条件分岐

  • ifとunless
iex> if 1 == 1 do
...>   true
...> else
...>   false
...> end
true
iex> if 1 == 1 do
...>   true
...> end
true

iex> unless 1 == 1 do
...>   true
...> else
...>   false
...> end
false
iex> unless 1 == 1 do
...>   true
...> end
nil
  • case
iex> case {:ok, "Successful"} do
...>   {:ok, result} -> result
...>   {:error} -> "oops!"
...>   _ -> "Catch all"
...> end
"Successful"

Note:

caseはどれにもマッチしないとエラーになる。
そのため_(アンダースコア)にて、最後に全てを取得している。
_(アンダースコア)変数は、代入しても使用しない変数として使うことができる。
(但し、参照しようとするとエラーになる)
caseにガード句を使ったサンプル。

Example:

iex> case [1, 2, 3] do
...>   [1, x, 3] when x > 1 -> x
...>   _ -> "Catch all"
...> end
2
  • cond
iex> cond do
...>   1 + 1 == 1 -> "1 + 1 = 1"
...>   2 + 2 == 4 -> "2 + 2 = 4"
...>   3 + 3 == 6 -> "3 + 3 = 6"
...> end
"2 + 2 = 4"

Note:

最後までマッチしないとエーらになる。

iex(1)> cond do
...(1)>   1 + 1 == 1 -> "1 + 1 = 1"
...(1)>   2 + 2 == 3 -> "2 + 2 = 3"
...(1)> end
** (CondClauseError) no cond clause evaluated to a true value
  • for
    一応、forもあるが推奨しない。forでできるならEnumか再帰で処理できる。
    一応サンプルを載せておく。

Example:

iex> for e <- [1, 2, 3] do
...>   IO.puts e
...> end
1
2
3
[:ok, :ok, :ok]

関数

  • 無名関数
iex> sum = fn(x, y) -> x + y end
#Function<12.54118792/2 in :erl_eval.expr/5>
iex> sum.(1, 2)
3

iex> sum = &(&1 + &2)
&:erlang.+/2
iex> sum.(1, 2)
3
  • 名前付き関数

Example:

defmodule FastRelearning do

  # Named Function
  def add(x, y) do
    addp(x, y)
  end

  # Private Function
  defp addp(x, y) do
    x + y
  end

  # with Guards
  def guard_def(x) when is_boolean(x) do
    x
  end

  # Default argment
  def default_arg(x \\ "Hello world") do
    IO.puts x
  end
end

iex> FastRelearning.add(1, 2)
3
iex> FastRelearning.addp(1, 2)
** (UndefinedFunctionError) undefined function FastRelearning.addp/2
    (fast_relearning) FastRelearning.addp(1, 2)
iex> FastRelearning.guard_def(true)
true
iex> FastRelearning.guard_def(1)
** (FunctionClauseError) no function clause matching in FastRelearning.guard_def/1
    (fast_relearning) lib/fast_relearning.ex:10: FastRelearning.guard_def(1)
iex> FastRelearning.default_arg
Hello world
:ok
iex> FastRelearning.default_arg("hogehoge")
hogehoge
:ok
  • パイプ演算子
パイプ演算子を使って関数を連続実行。
defmodule FastRelearning do
  def pipe1(x) do
    x + x
  end

  def pipe2(y) do
    y * y
  end

  def pipe3(z) do
    IO.puts z
  end
end

iex> import FastRelearning
nil
iex> 1 |> pipe1 |> pipe2 |> pipe3
4
:ok
Note:
第一引数は、最初に与えた値もしくは戻り値が入る。
今回の場合、最初の与えた値は1。
piep1で1+1が実行され、戻り値で2が返ってきている。
戻り値の2がpipe2の第一引数になっている。

モジュール定義

  • モジュール定義
iex> defmodule Test do
...>   def add(x, y) do
...>     x + y
...>   end
...> end
{:module, Test,
 ...,
 {:add, 2}}
iex> Test.add(1, 2)
3
iex> Test.add 1, 2
3
  • モジュールアトリビュート
defmodule FastRelearning do
  @message "Hello World"

  def message do
    IO.puts @message
  end
end

iex> FastRelearning.message
Hello World
:ok

Note:

モジュールのアトリビュートには、3つの目的がある。
- 注釈
- 定数
- 一時的な貯蔵

Elixirで使えるアトリビュート例
- @moduledoc ・・・ モジュールのドキュメントを記述する
- @doc ・・・ 関数やマクロのドキュメントを記述する
- @behaviour ・・・ ユーザ定義かOTP定義の振舞なのか区別するために使われる
- @before_compile ・・・ モジュールがコンパイルされる前に実行されるフック。(コンパイル直前にモジュールへ関数を注入できるらしい)
- @spec ・・・ 関数の仕様を記述する
- @callback ・・・ behaviourのコールバック仕様を記述する
- @type ・・・ @specの中での型を定義する
- @typep ・・・ @specの中でのプライベートな型を定義する
- @opaque ・・・ @specの中での未確定な型を定義する
モジュールアトリビュートを使った値の蓄積例
defmodule FastRelearning do
  Module.register_attribute __MODULE__, :value, accumulate: true

  @value {"hello", "world"}
  @value {"foo", "bar"}

  def get_value do
    @value
  end
end

iex> FastRelearning.get_value
[{"foo", "bar"}, {"hello", "world"}]
iexでやると面倒くさいので、ソースファイルを作成した方がいい。
  • 構造体
defmodule FastRelearning.User do
  defstruct name: "hoge", email: "hoge@test.com"
end

iex> %FastRelearning.User{}
%FastRelearning.User{email: "hoge@test.com", name: "hoge"}
iex> %FastRelearning.User{name: "foo", email: "bar@test.com"}
%FastRelearning.User{email: "bar@test.com", name: "foo"}

iex> user = %FastRelearning.User{}
%FastRelearning.User{email: "hoge@test.com", name: "hoge"}
iex> user.email
"hoge@test.com"
iex> user.name
"hoge"
iex> user = %{user | name: "foo"}
%FastRelearning.User{email: "hoge@test.com", name: "foo"}

iex> %{name: "foo"} = user
%FastRelearning.User{email: "hoge@test.com", name: "foo"}
iex> %{name: "bar"} = user
** (MatchError) no match of right hand side value: %FastRelearning.User{email: "hoge@test.com", name: "foo"}
  • alias: モジュールへ別名を付ける時に使う
defmodule AliasExample.Hoge do
  ...
end

defmodule AliasExample.Huge do
  ...
end

defmodule AliasExample.One do
  alias AliasExample.Hoge
  alias AliasExample.Huge, as: Huge
end

defmodule AliasExample.Multi. do
  alias AliasExample.{Hoge, Huge}
end

Note:

asオプションをなしで別名定義をすると、モジュール名の最後の部分が自動的に設定される。
以下は同じ意味になる。

"alias AliasExample.Hoge, as: Hoge" と "alias AliasExample.Hoge" は同じ意味になる。
  • import: 他のモジュールにある関数やマクロを修飾名をつけないで呼び出す時に使う
iex> count([1,2,3])
** (RuntimeError) undefined function: count/1
iex> import Enum, only: [count: 1]
nil
iex> count([1,2,3])
3

Note:

:only、:exceptオプションを使えば特定の関数だけ対象にしたり除外できる。
オプションがない場合は、importしたモジュールの全関数が対象になる。
  • require: マクロを展開させる時に使う
defmodule RequireExample do
  defmacro sample(arg1, arg2) do
    quote do
      ...
    end
  end
end

iex> RequireExample.sample(arg1, arg2)
エラーが発生し、requireしろとメッセージが表示される。
iex> require RequireExample
nil
iex> RequireExample.sample(arg1, arg2)
正常に実行される。

Note:

マクロを使うためには、コンパイル時にそのモジュールと実装が用意されている必要がある。
  • use: モジュールのusingを展開させる
defmodule UsingExample do
  defmacro __using__(_options) do
    quote do
      ...
      import unquote(__MODULE__)
      ...
    end
  end

  ...
end

defmodule UseExample do
  use UsingExample
end
上記の場合、UsingExample.using/1がUseExampleのuseしている場所で展開される。

ドキュメントの書き方

  • ラインコメント
defmodule FastRelearning do
  # Line Comment
end
  • モジュールドキュメント
defmodule FastRelearning do
  @moduledoc """
  This module is moduledoc example.
  """
end
  • 関数ドキュメント
defmodule FastRelearning do
  @moduledoc """
  This module is moduledoc example.
  """

  @doc """
  Print name function.

  ## Parameters

    - name: Your name String.

  ## Examples

      iex> FastRelearning.my_name_is("hoge")
      "My name is hoge!"

      iex> FastRelearning.my_name_is("foo")
      "My name is foo!"

  """
  def my_name_is(name) do
    "My name is " <> name <> "!"
  end
end

Note:

ヘルパーコマンドのhを使えば以下のようにモジュール/関数のドキュメントを取得できる。

iex(1)> h FastRelearning
* FastRelearning

This module is moduledoc example.

iex(2)> h FastRelearning.my_name_is
* def my_name_is(name)Print name function.## Parameters  - name: Your name String.## Examples    iex> FastRelearning.my_name_is("hoge")    "My name is hoge!"    iex> FastRelearning.my_name_is("foo")    "My name is foo!"
  • ExDoc
プロジェクトが必要。(記事の上の方で作成したプロジェクトを利用する)
適当にモジュールを作成し、モジュールドキュメントと関数ドキュメントを記述する。
defmodule FastRelearning do
  @moduledoc """
  This module is moduledoc example.
  """

  @doc """
  Print name function.

  ## Parameters

    - name: Your name String.

  ## Examples

      iex> FastRelearning.my_name_is("hoge")
      "My name is hoge!"

      iex> FastRelearning.my_name_is("foo")
      "My name is foo!"

  """
  @spec my_name_is(String.t) :: String.t
  def my_name_is(name) do
    "My name is " <> name <> "!"
  end
end

File: mix.exs

defmodule FastRelearning.Mixfile do
  ...

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [{:earmark, "~> 0.2.1", only: :dev},
     {:ex_doc, "~> 0.11", only: :dev}]
  end
end

> mix deps.get
Running dependency resolution
Dependency resolution completed
  earmark: 0.2.1
  ex_doc: 0.11.4
* Getting earmark (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/earmark-0.2.1.tar)
Fetched package
* Getting ex_doc (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/ex_doc-0.11.4.tar)
Fetched package

> mix docs
...
Docs successfully generated.
View them at "doc/index.html".
生成が成功したら、プロジェクトディレクトリにあるdoc配下を確認し作成したモジュールのhtmlを確認する。

ExUnit

  • テストの実行
> mix test
Compiled lib/fast_relearning.ex
.

Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 test, 0 failures

Randomized with seed 31000
  • テスト
ドキュメントの部分で作ったモジュール/関数のテストを追加して行ってみる。
defmodule FastRelearning do
  @moduledoc """
  This module is moduledoc example.
  """

  @doc """
  Print name function.

  ## Parameters

    - name: Your name String.

  ## Examples

      iex> FastRelearning.my_name_is("hoge")
      "My name is hoge!"

      iex> FastRelearning.my_name_is("foo")
      "My name is foo!"

  """
  @spec my_name_is(String.t) :: String.t
  def my_name_is(name) do
    "My name is " <> name <> "!"
  end
end
defmodule FastRelearningTest do
  use ExUnit.Case
  doctest FastRelearning

  test "the truth" do
    assert 1 + 1 == 2
  end

  test "my name is" do
    assert "My name is hoge!" == FastRelearning.my_name_is("hoge")
    assert "My name is hoge!" != FastRelearning.my_name_is("foo")
  end
end

> mix test
Compiled lib/fast_relearning.ex
....

Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
4 tests, 0 failures

Randomized with seed 288000
  • テストの初期値
defmodule FastRelearningTest do
  use ExUnit.Case
  doctest FastRelearning

  setup_all do
    {:ok, name: "hoge"}
  end

  test "the truth" do
    assert 1 + 1 == 2
  end

  test "my name is" do
    assert "My name is hoge!" == FastRelearning.my_name_is("hoge")
    assert "My name is hoge!" != FastRelearning.my_name_is("foo")
  end

  test "setup initial value", state do
    assert "My name is hoge!" == FastRelearning.my_name_is(state[:name])
  end
end

>mix test
.....

Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
5 tests, 0 failures

Randomized with seed 254000
  • PowerAssertEx
defmodule FastRelearning.Mixfile do
  ...

  # Dependencies can be Hex packages:
  #
  #   {:mydep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [{:power_assert, "~> 0.0.8"}]
  end
end

> mix deps.get
Running dependency resolution
Dependency resolution completed
  power_assert: 0.0.8
* Getting power_assert (Hex package)
Checking package (https://s3.amazonaws.com/s3.hex.pm/tarballs/power_assert-0.0.8.tar)
Fetched package
defmodule FastRelearningTest do
  #use ExUnit.Case
  use PowerAssert
  doctest FastRelearning

  ...

  test "power assert example" do
    array = [1, 2, 3, 4, 5, 6]
    index = 2
    two = 2
    assert array |> Enum.at(index) == 2
  end
end

> mix test
test/fast_relearning_test.exs:26: warning: variable two is unused
test/fast_relearning_test.exs:26: warning: variable two is unused
.

  1) test power assert example (FastRelearningTest)
     test/fast_relearning_test.exs:23
     array |> Enum.at(index) == 2
     |             |  |
     |             3  2
     [1, 2, 3, 4, 5, 6]
     stacktrace:
       test/fast_relearning_test.exs:27

....

Finished in 0.1 seconds (0.1s on load, 0.00s on tests)
6 tests, 1 failure

Randomized with seed 532000

シギル(Sigil)

シギルの一覧
  • ~C: ノーエスケープまたは補間と文字リストを生成
  • ~c: エスケープと補間と文字リストを生成
  • ~R: ノーエスケープまたは補間で正規表現を生成
  • ~r: エスケープおよび補間で正規表現を生成
  • ~S: ノーエスケープまたは補間を含む文字列を生成
  • ~s: エスケープと補間して文字列を生成
  • ~W: ノーエスケープまたは補間のリストを生成
  • ~w: エスケープと補間してリストを生成
区切り文字の一覧
  • <…> 山形括弧のペア
  • {…} 中括弧のペア
  • […] 角括弧のペア
  • (…) 括弧のペア
  • |…| パイプのペア
  • /…/ スラッシュのペア
  • “…” 二重引用符のペア
  • ‘…’ 単一引用符のペア
大体のサンプルは/…/で書かれているがそれ以外でも使える。
  • char型のリスト
iex> ~c/2 + 7 = #{2 + 7}/
'2 + 7 = 9'
iex> ~C/2 + 7 = #{2 + 7}/
'2 + 7 = \#{2 + 7}'
  • 正規表現
iex> re = ~r/elixir/
~r/elixir/
iex> "Elixir" =~ re
false
iex> "elixir" =~ re
true
iex> "elixir" = re
** (MatchError) no match of right hand side value: ~r/elixir/

iex(8)> Regex.split(~r/_/, "100000000")
["100000000"]
iex(9)> Regex.split(~r/_/, "100_000_000")
["100", "000", "000"]
  • 文字列
iex> ~s/enjoy elixir #{String.downcase "School"}/
"enjoy elixir school"
iex> ~S/enjoy elixir #{String.downcase "School"}/
"enjoy elixir \#{String.downcase \"School\"}"
  • ワードリスト
iex> ~w/Let's play elixir #{"school"}/
["Let's", "play", "elixir", "school"]
iex> ~W/Let's play elixir #{"school"}/
["Let's", "play", "elixir", "\#{\"school\"}"]
  • 自作シギル
defmodule FastRelearning do
  def sigil_u(string, []), do: String.upcase(string)endiex> import FastRelearningniliex> ~u/elixir shcool/
"ELIXIR SHCOOL"

Speaking to oneself

Elixir Schoolに入校しました。
とりあえず、Basicsまで終了。色々と思い出してきた。
途中横道にそれて変な検証してたりしたけど気にしない。
次はAdvancedまで終わらせる。

Bibliography

人気の投稿