Elixir - 如何在Shell中调用模块函数

14
在Elixir中,是否有一种方法可以直接从shell调用模块函数,而不必一定需要启动会话? 让我举个例子:
作为我的Phoenix应用程序的一部分,我编写了一个辅助模块,可以从相邻的会话中运行。 这是一个超级简化的版本:
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

另外,我尝试将我的模块重新定义为自定义Mix任务,具体描述在此处:https://elixirschool.com/en/lessons/basics/mix-tasks/#custom-mix-task

但是这也失败了,因为我的模块依赖于一些导入/别名,例如MyApp.Repo,并且尝试使用mix helperiex -S mix helper执行文件会导致

** (ArgumentError) repo MyApp.Repo is not started, please ensure it is part of your supervision tree

如果没有其他办法,脚本只能在运行iex -S mix的情况下成功执行,那没关系...但是如果有办法设置一条命令在shell中运行并根据需要执行此操作,那就太好了。

1个回答

19

您可以使用 mix run 命令并添加 -e 参数来完成此操作:

$ mix run -e MyApp.Helper.start

或者如果您有要传递给函数的参数:

$ mix run -e "MyApp.Helper.start(:foo, :bar)"

mix help run 中得知:

如果想要在当前应用程序中执行脚本或通过命令行标志配置应用程序,可以通过传递脚本文件或评估表达式来实现:

mix run my_app_script.exs arg1 arg2 arg3
mix run -e "MyApp.start" -- arg1 arg2 arg3

1
值得一提的是,如果您想在Mix项目之外运行单行命令,可以将--no-mix-exs作为参数传递;例如:mix run --no-mix-exs -e 'IO.puts(:hello)' - Darragh Enright

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接