Elixir - 从 shell 调用模块函数
Elixir - call a module function from the shell
在 Elixir 中,有没有一种方法可以直接从 shell 调用模块函数,而不必启动 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
但这也失败了,因为我的模块依赖于某些 imports/aliases,例如 MyApp.Repo
,并且尝试使用 mix helper
或 iex -S mix helper
执行文件导致
** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree
如果没有办法解决这个问题并且脚本只能在 运行ning iex -S mix
内成功执行,那没关系......但是如果有办法设置的话一行代码可以从 shell 中 运行 让它根据需要执行,那就是蜜蜂的膝盖。
您可以将 mix run
与 -e
参数一起使用:
$ mix run -e MyApp.Helper.start
或者如果您有要传递给函数的参数:
$ mix run -e "MyApp.Helper.start(:foo, :bar)"
来自mix help run
:
If there is a desire to execute a script within the current
application or configure the application via command line flags, it is
possible to do so by passing a script file or an eval expression to
the command:
mix run my_app_script.exs arg1 arg2 arg3
mix run -e "MyApp.start" -- arg1 arg2 arg3
在 Elixir 中,有没有一种方法可以直接从 shell 调用模块函数,而不必启动 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
但这也失败了,因为我的模块依赖于某些 imports/aliases,例如 MyApp.Repo
,并且尝试使用 mix helper
或 iex -S mix helper
执行文件导致
** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree
如果没有办法解决这个问题并且脚本只能在 运行ning iex -S mix
内成功执行,那没关系......但是如果有办法设置的话一行代码可以从 shell 中 运行 让它根据需要执行,那就是蜜蜂的膝盖。
您可以将 mix run
与 -e
参数一起使用:
$ mix run -e MyApp.Helper.start
或者如果您有要传递给函数的参数:
$ mix run -e "MyApp.Helper.start(:foo, :bar)"
来自mix help run
:
If there is a desire to execute a script within the current application or configure the application via command line flags, it is possible to do so by passing a script file or an eval expression to the command:
mix run my_app_script.exs arg1 arg2 arg3 mix run -e "MyApp.start" -- arg1 arg2 arg3