是否可以在没有编译的情况下运行erlang?

时间:2013-04-12 10:09:53

标签: erlang runtime

是否有任何用于Erlang的VM允许您在运行中进行编译而不是之前进行编译?

有可能从shell编译,感谢Martin。

Now, from the Erlang shell (or some other module!):


1> compile:file("mymod.erl").
{ok,mymod}
2> mymod:myfun().
Hello Joe

这样做有利有弊吗? 你还能热插拔代码吗? 它是处理代码的常规用例吗? 那么编译器最终会给你带来什么好处呢?

3 个答案:

答案 0 :(得分:6)

从Erlang shell中,您可以使用c("path/to/module.erl")动态编译模块。您还可以通过compile模块访问此功能,特别是compile:file/{1,2}功能。

例如,假设我们有一个文件mymod.erl

-module(mymod).
-export([myfun/0]).

myfun() -> io:format("Hello Joe~n").

现在,从Erlang shell(或其他一些模块!):

1> compile:file("mymod.erl").
{ok,mymod}
2> mymod:myfun().
Hello Joe

有关详细信息,请参阅compile模块上的Erldocs。

您可以在运行时对Erlang编译器做很多事情。例如,您可以动态生成模块的代码(使用erl_syntax!)然后编译它,甚至不用compile:forms/{1,2}将其写入文件。

(插入关于强大权力和重大责任的标准演讲。)


  

你还能热插拔代码吗?

  

处理代码是常规用例吗?

没有。通常,Erlang代码会提前编译成BEAM字节码。根据Erlang是否以embedded or interactive模式启动,模块要么在启动时加载,要么在引用时动态加载。如果您正在构建release,那么基本上必须提前编译。

  

编译器最终给你带来了哪些好处?

嗯,首先,我们可以构建紧凑版本,而不需要编译器等不必要的组件。当然,我们也可以获得提前编译的所有传统优势,特别是不必浪费时间编译。

总结一下,除非您完全理解其含义并且非常好的理由不提前编译代码,否则请遵循标准做法。

答案 1 :(得分:5)

Erlang VM只能运行已编译的代码!如果你想解释Erlang代码,那么你需要一个解释器。模块erl_eval实现了Erlang解释器,是标准Erlang / OTP发行版的一部分。 Erlang shell使用它来解释输入的表达式。

Erlang VM中的所有代码处理,无论是编译,加载还是更新,都是在模块级别完成的,因此无法编译或加载一个函数。 Erlang编译器是用Erlang编写的,并且始终可用,可以编译成文件或二进制文件,可以立即加载到系统中。正如@MartinTörnwall所指出的,使用c(module)从shell编译模块实际上是在动态编译。

因此,在模块级别使用代码时,无需动态编译代码。只是当前系统没有设计为以这种方式工作,默认情况下,当它尝试加载模块时,它只查找预编译的目标文件.beam文件。

答案 2 :(得分:1)

Erlang有一名翻译escript。整个Erlang存档可以用脚本编写。几乎所有功能都可用。

默认情况下,将解释脚本。您可以通过在脚本中包含-mode(compile).来强制编译它。

虽然这取决于您设计应用程序的方式,但通常的做法是编译和运行.erl文件,而不是使用escript文件。

所以现在你有很多选择。

  1. 使用c(my_module)将.erl文件编译为.beam,这会自动加载.beam文件。因此现有的VM可以即时运行它。在代码中,您可以使用编译模块函数(如file,purge和load)来加载和运行它。
  2. 使用erlc,erl -make,rebar等编译并保留.erl文件(Erlang有丰富的支持),然后运行它。您可以构建存档,启动脚本,rel等来管理Erlang软件的运行和发布。这通常是生产的做法。
  3. 使用escript并以解释模式运行所有内容。
  4. 使用escript并给出-mode(编译)选项告诉Erlang VM在运行时(开始运行escript时)编译代码并运行编译代码(在内存中)
  5. 这样做有利有弊吗?

    编译代码比解释代码更快。我现在在Erlang中没有看到任何其他内容,因为两者都支持所有内容。 Erlang甚至支持组合(从解释代码调用编译代码)

    您仍然可以热插拔代码吗?

    在所有情况下都是。您的代码也应该能够处理这个问题。

    处理代码是常规用例吗?

    生产选项2。学习/简单开发的选项1。选项3和4需要基于特定要求(可能是一次运行)。

    编译器最终给你带来了哪些好处?

    为了说清楚,erlc程序提供了在Erlang系统中运行所有编译器的通用方法,compile模块提供了Erlang编译器的接口。编译器提供中间二进制.beam文件,这有助于比解释对应文件更快地运行Erlang代码。它们还会捕获语法错误(编译错误)。