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

pto*_*oos 2 erlang runtime

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

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

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


1> compile:file("mymod.erl").
{ok,mymod}
2> mymod:myfun().
Hello Joe
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*all 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").
Run Code Online (Sandbox Code Playgroud)

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

1> compile:file("mymod.erl").
{ok,mymod}
2> mymod:myfun().
Hello Joe
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅编译模块上的Erldocs .

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

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


你还能热插拔代码吗?

是.

它是处理代码的常规用例吗?

通常,Erlang代码会提前编译成BEAM字节码.根据Erlang是以嵌入模式还是以交互模式启动,模块要么在启动时加载,要么在引用时动态加载.如果要构建一个版本,则基本上必须提前编译.

那么编译器最终给你带来了什么好处呢?

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

总结一下,除非你完全理解其含义并且有充分的理由不提前编译代码,否则请遵循标准做法.


rvi*_*ing 5

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

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

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