はじめに
Elixirを使ったプログラミングをする際は、デバッグや動作確認を目的としてiexを使用する機会が多いことと思います。この記事では、iexの使用を便利にするコマンドやツールを紹介します。
iexを再起動せずコンパイルする
iex -S mix
のようなコマンドでElixirのコードを実行した際、コードに変更を加えてから再度iexで動作を確認したいケースがあります。その場合、iexを一旦終了してからもう一度起動することが多いかと思いますが、recompile/0 を使うことで、iexの再起動なしにコンパイルすることができます。つまり、iexで次のコマンドを実行するだけです。
iex(1)> recompile
なお、 r/1 を使うことで、特定のモジュールのコードのみを再コンパイルすることも可能です。
v
で以前の出力結果を使う
IEx.Helpers.v/1 を使うことで、iexの最後に出力された値を取得することが可能です。そのため、以下のようなことができます。
iex(1)> 100 + 300
400
iex(2)> v - 34
366
また、 IEx.Helpers.v/1
にマイナスの値 n
指定すると、最後からn番目の値を取り出すことができます。
iex(1)> 100 + 300
400
iex(2)> v - 34
366
iex(3)> v(-2)
400
iexの履歴を保持する
通常、iexは終了するたびにその履歴が失われてしまいますが、次のようにフラグをセットすることで履歴を維持することができます。
export ERL_AFLAGS="-kernel shell_history enabled"
aliasを有効にする
深いネストを持つmoduleをiexで複数回使用するようなケースでは、最初に alias
を宣言することで入力が容易になります。
例えば、以下のようなmodule、functionを持っているとしましょう。
defmodule Happy.World.Greeting do
def hello(), do: :hello
end
defmodule Happy.World.Math do
def plus(a, b), do: a + b
end
この場合、以下のように alias
を宣言することで、moduleを省略して使用することができるようになります。
iex(1)> alias Happy.World.{Greeting, Math}
[Happy.World.Greeting, Happy.World.Math]
iex(2)> Greeting.hello()
:hello
iex(3)> Math.plus(1, 2)
3
.iex.exs
でiex開始時の処理を定義する
iexを開始するディレクトリに .iex.exs
を配置してiex開始時に実行したい処理を記述しておくと、iexはその内容を自動的にロードして評価します。例えば、以下のような .iex.exs
ファイルを配置したとしましょう。
alias Happy.World.{Greeting, Math}
IO.puts("Start iex!!")
この状態でiexを開始すると、上記の内容が評価され、iexに反映されます。
$ iex -S mix
Erlang/OTP 21 [erts-10.0.5] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] [dtrace]
Interactive Elixir (1.7.2) - press Ctrl+C to exit (type h() ENTER for help)
Start iex!!
iex(1)> Greeting.hello()
:hello
iex(2)> Math.plus(1, 2)
3
また、 ~/.iex.exs
を配置することで、グローバルな初期化処理を定義することもできます。
h
でドキュメントを確認する
IEx.Helpers.h/1 を使うことで、moduleやfunctionのドキュメントを出力することができます。以下の例を見てみましょう。
iex(1)> h Enum.join
def join(enumerable, joiner \\ "")
@spec join(t(), String.t()) :: String.t()
Joins the given enumerable into a binary using joiner as a separator.
If joiner is not passed at all, it defaults to the empty binary.
All items in the enumerable must be convertible to a binary, otherwise an error
is raised.
## Examples
iex> Enum.join([1, 2, 3])
"123"
iex> Enum.join([1, 2, 3], " = ")
"1 = 2 = 3"
i
で情報を出力する
IEx.Helpers.i/1 を使うと、指定した変数、値の情報を出力することができます。以下の例を見てみましょう。
iex(1)> name = "Tsuyoshi"
"Tsuyoshi"
iex(2)> i name
Term
"Tsuyoshi"
Data type
BitString
Byte size
8
Description
This is a string: a UTF-8 encoded binary. It's printed surrounded by
"double quotes" because all UTF-8 encoded codepoints in it are printable.
Raw representation
<<84, 115, 117, 121, 111, 115, 104, 105>>
Reference modules
String, :binary
Implemented protocols
Inspect, IEx.Info, String.Chars, List.Chars, Collectable
複数行入力する
iexは、改行が行われた段階で複数行入力が必要かどうかを判断し、必要であれば自動的に複数行入力状態となります。
例えば以下の例では、1行目でStringの入力を開始しているものの、対となるダブルクォーテーションが無いために複数行入力となります。
iex(1)> message = "I am Tsuyoshi.
...(1)> I am happy.
...(1)> I don't know why.
...(1)> But I am happy."
"I am Tsuyoshi.\nI am happy.\nI don't know why.\nBut I am happy."
また、以下の例では defmodule
の do
に対応する end
が1行目に無いため、複数行入力となります。
iex(1)> defmodule Happy do
...(1)> def sayHappy, do: "I'm happy"
...(1)> end
{:module, Happy,
<<70, 79, 82, 49, 0, 0, 3, 248, 66, 69, 65, 77, 65, 116, 85, 56, 0, 0, 0, 128,
0, 0, 0, 13, 12, 69, 108, 105, 120, 105, 114, 46, 72, 97, 112, 112, 121, 8,
95, 95, 105, 110, 102, 111, 95, 95, 7, ...>>, {:sayHappy, 0}}
しかし、1行だけで式の評価が可能になってしまう場合、自動的に複数行入力とはなりません。
例えば、以下のようなコードをiexで書きたいとしましょう。
[1, 2, 3]
|> Kernel.++([4, 5])
|> Enum.map(fn n -> n + 5 end)
これをこのままiexで入力しようとしても、1行目だけで評価が終わってしまいます。
iex(1)> [1, 2, 3]
[1, 2, 3]
このような場合は、(
を先頭に付けることで複数行入力を実現できます。(式全体を()
で囲みます)
iex(1)> (
...(1)> [1, 2, 3]
...(1)> |> Kernel.++([4, 5])
...(1)> |> Enum.map(fn n -> n + 5 end)
...(1)> )
[6, 7, 8, 9, 10]