Code.ensure_loaded? in .iex.exs

醉酒当歌 提交于 2019-12-11 05:53:08

问题


I have an elixir console configuration stored in .iex.exs:

if Code.ensure_loaded?(MyApp.Repo) do
  alias MyApp.Repo
end

I want to have an ability to run both iex and iex -S mix. I'll have exception if I remove condition on iex.

But this conditions doesn't work well! Even on iex -S mix I have (module Repo is not available) error if I'm trying to invoke Repo.get(...). So, my questions are:

  1. Why Code.ensure_loaded? doesn't work here?
  2. How can I fix that?

回答1:


This is a matter of scoping. Inside a block, you have this alias defined:

if Code.ensure_loaded?(MyApp.Repo) do
  alias MyApp.Repo
  Repo.get(...) #⇒ available
end

To define an alias IEx-wide, you should call it outside of any block:

alias MyApp.Repo

You do not need a conditional if Code.ensure_loaded?(MyApp.Repo) when IEx is executed with iex -S mix, all the dependencies will be loaded for you automagically. For pure iex this might be done in more cumbersome way:

defmodule FileExt do
  def ls_all(dir, acc \\ []) do
    case File.ls(dir) do
      {:ok, list} -> list |> Enum.reduce(acc, fn f, acc ->
          fullname = dir <> "/" <> f
          if fullname |> File.dir?, do: ls_all(fullname, acc), else: acc ++ [fullname]
        end)
      {:error, e} ->
        IO.puts "Unable to list. Reason: #{e}"
        acc
    end
  end

  def require_lib do
    try do
      "lib" |> FileExt.ls_all |> Kernel.ParallelRequire.files
    rescue
      e in UndefinedFunctionError -> Code.ensure_loaded?(MyApp.Repo)
    end
  end
end

try do
  MyApp.Repo.get
rescue
  e in UndefinedFunctionError -> FileExt.require_lib
end

alias MyApp.Repo

The above would load all files from the "lib" directory.

Though I would shut the perfectionism up here and go with iex -S mix always, without check:

Code.ensure_loaded?(MyApp.Repo)
alias MyApp.Repo


来源:https://stackoverflow.com/questions/39503311/code-ensure-loaded-in-iex-exs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!