Есть ли в Эликсире способ вызвать функцию модуля непосредственно из оболочки, без необходимости запуска сеанса iex -S mix
? Позвольте мне проиллюстрировать это сценарием:
Как часть моего приложения Phoenix, я написал вспомогательный модуль, который должен запускаться из соседнего сеанса iex -S mix
. Вот супер-упрощенная версия:
defmodule MyApp.Helper do
# For the demo, these imports/aliases are not used - but they're there in real life.
import Ecto.Query
alias MyApp.Repo
def start do
{:ok, "Done"}
end
end
Если я запускаю сеанс с iex -S mix
, а затем запускаю функцию из модуля, все работает нормально:
$ iex -S mix
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 2 files (.ex)
Interactive Elixir (1.5.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> MyApp.Helper.start
{:ok, "Done"}
А затем ctrl-c a
, чтобы закрыть сеанс.
Однако, если я попробую что-то вроде:
$ iex -S mix MyApp.Helper.start
Это приводит к
Erlang/OTP 20 [erts-9.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
Compiling 2 files (.ex)
** (Mix) The task "MyApp.Helper.start" could not be found
В качестве альтернативы я попытался переопределить свой модуль как пользовательскую смешанную задачу, как описано здесь: https://elixirschool.com/en/lessons/basics/mix-tasks/#custom-mix-task
но это также не удалось, потому что мой модуль зависит от некоторых импортов/псевдонимов, таких как MyApp.Repo
, и попытка выполнить файл с mix helper
или iex -S mix helper
привела к
** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree
Если нет никакого способа обойти это, и сценарий может быть успешно выполнен только из работающего iex -S mix
, это нормально... но если бы был способ настроить все таким образом, чтобы однострочный код мог запускаться из оболочки, чтобы заставить это выполниться по мере необходимости, это будут колени пчелы.