【问题标题】:Is it possible to run erlang without compilation?是否可以在不编译的情况下运行 erlang?
【发布时间】:2013-06-26 02:09:22
【问题描述】:

是否有任何适用于 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

这样做有什么好处或坏处吗? 你还能热交换代码吗? 它是处理代码的常规用例吗? 那么编译器到底给你带来了什么好处呢?

【问题讨论】:

标签: erlang runtime


【解决方案1】:

在 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,则基本上必须提前编译。

那么编译器到底给你带来了什么好处呢?

好吧,一方面,我们可以构建紧凑的版本,而无需编译器等不必要的组件。当然,我们还获得了提前编译的所有传统优势,尤其是不必一直浪费时间进行编译。

总而言之,除非您完全理解其中的含义并且有很好的理由不提前编译您的代码,否则请遵循标准做法。

【讨论】:

  • 抱歉,这带来了更多问题。将它们添加到原始主题中
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    Erlang 有一个解释器 escript。整个 Erlang 档案都可以用脚本编写。几乎所有功能都可用。

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

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

    所以现在你有很多选择。

    1. 使用c(my_module) 将 .erl 文件编译为 .beam,这会自动加载 .beam 文件。所以现有的虚拟机可以运行它。在代码中,您可以使用编译模块功能,如文件、清除和加载来动态加载和运行它。
    2. 使用 erlc、erl -make、rebar 等(Erlang 有丰富的支持)编译并保存 .erl 文件,然后运行它。您可以构建档案、启动脚本、rel 等来管理 Erlang 软件的运行和发布。这通常是生产实践。
    3. 使用 escript 并以解释模式运行所有内容。
    4. 使用 escript 并提供 -mode(compile) 选项告诉 Erlang VM 在运行时(开始运行 escript 时)编译代码并运行编译后的代码(在内存中)

    这样做有什么好处或坏处吗?

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

    您还能热交换代码吗?

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

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

    用于生产的选项 2。 1 用于学习/简单开发的选项。选项 3 和 4 需要根据具体要求(可能是一次运行)。

    那么编译器到底给你带来了什么好处呢?

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      • 2013-11-17
      • 2017-09-02
      • 2012-07-06
      • 1970-01-01
      相关资源
      最近更新 更多