Code.ensure_loaded? в.iex.exs

У меня есть консольная конфигурация эликсира в .iex.exs:

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

Я хочу иметь возможность запустить оба iex а также iex -S mix, У меня будет исключение, если я уберу условие на iex,

Но эти условия не работают хорошо! Даже на iex -S mix я имею (module Repo is not available) ошибка, если я пытаюсь вызвать Repo.get(...), Итак, мои вопросы:

  1. Зачем Code.ensure_loaded? здесь не работает?
  2. Как я могу это исправить?

1 ответ

Это вопрос объема. Внутри блока у вас есть этот псевдоним:

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

Чтобы определить alias IEx-wide, вы должны вызывать его вне любого блока:

alias MyApp.Repo

Вам не нужно условное if Code.ensure_loaded?(MyApp.Repo) когда IEx выполняется с iex -S mixвсе зависимости будут загружены для вас автоматически. Для чистого iex это может быть сделано более громоздким способом:

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

Выше будет загружать все файлы из "lib" каталог.

Хотя я бы заткнул перфекционизм здесь и пошел с iex -S mix всегда без проверки:

Code.ensure_loaded?(MyApp.Repo)
alias MyApp.Repo
Другие вопросы по тегам