使用 Erlang 的 Elixir 模块失败

Posted

技术标签:

【中文标题】使用 Erlang 的 Elixir 模块失败【英文标题】:Using Elixir module from Erlang fails 【发布时间】:2017-12-13 12:42:52 【问题描述】:

我正在尝试在 Erlang 模块中使用从 Elixir 源代码编译的光束文件。运行 Erlang 节点时会引发错误,但我可以直接使用 Elixir 中的代码。

Elixir 模块:

defmodule Recursion do
  def print_multiple_times(msg, n) when n <= 1 do
    IO.puts msg
  end

  def print_multiple_times(msg, n) do
    IO.puts msg
    print_multiple_times(msg, n - 1)
  end
end

Erlang 模块:

-module(use_recur).
-define(elixir__recursion, 'Elixir.Recursion').

-export([hey/0]).

hey() ->
    ?elixir__recursion:print_multiple_times("Hello!", 3).

同时编译:

$ rm -f *.beam $ elixirc recursion.ex $ erlc use_recur.erl

运行 Erlang:

$ erl -run use_recur hey -run init stop -noshell "init 终止于 do_boot",undef,['Elixir.IO',puts,["Hello!"],[],'Elixir .Recursion',print_multiple_times,2,[file,"recursion.ex",line,7],init,start_em,1,[],init,do_boot,3,[]] init 终止于 do_boot (undef,[Elixir.IO,puts,Hello!,[],Elixir.Recursion,print_multiple_times,2,[,],init ,start_em,1,[],init,do_boot,3,[]])

正在将故障转储写入:erl_crash.dump...done

灵药脚本:

Recursion.print_multiple_times "Hello!", 3

运行成功:

$ elixir elx_recur.exs  
Hello!
Hello!
Hello!

为什么会这样?我想说 Erlang 的输出应该是一样的。

【问题讨论】:

您可能需要使用-pa(例如erl -pa /path/to/elixir/ebin ...)将包含Elixir 光束文件的目录添加到erl。该错误意味着 Erlang 找不到 'Elixir.IO' 模块。 Alexanders-MacBook-Air:~ alexander$ erl -pa /usr/local/Cellar/elixir/1.4.5/lib/elixir/ebin -run use_recur hey -run init stop -noshell 你好!你好!你好! Alexanders-MacBook-Air:~ alexander$ ls /usr/local/Cellar/elixir/1.4.5/lib/elixir/ebin/ | grep Elixir.String.beam Elixir.String.beam 您可以将评论重新发布为答案以便我标记它吗? 【参考方案1】:

错误意味着 Erlang 找不到名为 'Elixir.IO' 的模块。这个模块是核心 Elixir 的一部分。您需要使用-pa(或其他类似标志,如-pz)将Elixir 安装的ebin 文件夹添加到Erlang 的加载路径中,以使Erlang 加载Elixir 的核心库,因为该文件夹包含已编译的.beam Elixir 核心文件,包括Elixir.IO.beam

erl -pa /path/to/elixir/ebin ...

【讨论】:

以上是关于使用 Erlang 的 Elixir 模块失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 Elixir 和 Erlang ssl 模块获取 SSL 证书

在 Elixir 或 Erlang 中,如何在运行时动态创建和加载模块?

如何在Elixir或Erlang中在运行时动态创建和加载模块?

Elixir io_lib 调用 erlang

Elixir/Erlang 中的命名函数是不是有等效于 __MODULE__ 的方法?

如何使用elixir测量磁盘大小?