In Elixir, is there a way to call a module function directly from the shell, without necessarily needing to start an iex -S mix
session? Let me illustrate with a scenario:
As part of my Phoenix app, I've written a helper module that is to be run from an adjacent iex -S mix
session. Here's a super-simplified version:
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
If I start the session with iex -S mix
and then run a function from the module, it all works fine:
$ 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"}
And then ctrl-c a
to close the session.
However, if I try something like:
$ iex -S mix MyApp.Helper.start
That results in
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
Alternately, I tried redefining my module as a custom mix task, as described here: https://elixirschool.com/en/lessons/basics/mix-tasks/#custom-mix-task
but that also failed, because my module depends on some imports/aliases like MyApp.Repo
, and trying to execute the file with either mix helper
or iex -S mix helper
resulted in
** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree
If there's no way around this and the script can only be successfully executed from within a running iex -S mix
, that's fine... but if there was a way to set things up so a one-liner could run from the shell to get this to execute as-needed, that'd be the bee's knees.
--no-mix-exs
as an argument; e.g:mix run --no-mix-exs -e 'IO.puts(:hello)'
– Fenestration