簡易的な確認
簡易的には__ENV__.requires
でimport
したモジュールを確認できます。
iex(1)> __ENV__.requires
[IEx.Helpers, Kernel, Kernel.Typespec]
iex(2)> import Ecto.Query
nil
iex(3)> __ENV__.requires
[Ecto.Query, IEx.Helpers, Kernel, Kernel.Typespec]
__ENV__.requires
にはrequire
したものも含まれます。
特定の関数やマクロがimportされているかどうかは__ENV__.functions
と__ENV__.macros
で確認できます。
カスタムヘルパー
__ENV__
を何度もタイプするのは面倒くさいので、自分用のIExペルパーを書いて.iex.exs
に追加してみました。(こういうマクロの使い方がいいのかどうかはよくわかりませんが)
残念なことに、今のところ.iex.exs
で定義したモジュールは.iex.exs
内でimportすることはできないため、セッション開始後に手動でimportする必要があります。
defmodule IEx.MyHelpers do
def default_env do
__ENV__
end
defmacro env do
quote do
__ENV__
end
end
defmacro alias do
quote do
__ENV__.aliases
end
end
[:requires, :functions, :macros] |> Enum.each(fn name ->
defmacro unquote(name)(option \\ :imported) do
name = unquote(name)
import MapSet
quote bind_quoted: [option: option, name: name] do
case option do
x when x in [:a, :all] -> __ENV__ |> Map.get(name)
x when x in [:d, :default] -> default_env |> Map.get(name)
x when x in [:i, :imported] ->
difference(new(__ENV__ |> Map.get(name)),
new(default_env |> Map.get(name)))
|> MapSet.to_list
end
end
end
end)
defmacro imported(option \\ :imported) do
quote bind_quoted: [option: option] do
f = functions(option) |> (fn x -> %{functions: x} end).()
m = macros(option) |> (fn x -> %{macros: x} end).()
Map.merge(f, m)
end
end
end
alias IEx.MyHelpers
セッション開始後にimport
した関数・マクロを表示できるので、__ENV__
を見るよりは少しだけ見やすいです。
iex(1)> import MyHelpers
nil
iex(2)> import Ecto.Query, only: [select: 3]
nil
iex(3)> imported
%{functions: [{IEx.MyHelpers, [default_env: 0]}],
macros: [{Ecto.Query, [select: 3]},
{IEx.MyHelpers,
[alias: 0, env: 0, functions: 0, functions: 1, imported: 0, imported: 1,
macros: 0, macros: 1, requires: 0]}]}
参考資料
[Elixir: How to define multiple macros using a List as a variable? (StackOverflow)]
(http://stackoverflow.com/questions/37236450/elixir-how-to-define-multiple-macros-using-a-list-as-a-variable)
[Support delayed evaluation of code in .iex.exs (Github)]
(https://github.com/elixir-lang/elixir/issues/3328)