如何运行Elixir或Erlang编译的梁文件?

时间:2014-08-20 21:01:37

标签: erlang elixir

我已经安装了Erlang / OTP和Elixir,并使用以下命令将HelloWorld程序编译成BEAM:

elixirc test.ex

其中一个名为Elixir.Hello.beam的文件

如何运行此文件?

3 个答案:

答案 0 :(得分:36)

简短回答:如果不知道源文件的内容,就无法确定:)

有几种方法可以运行Elixir代码。这个答案将概述可与Elixir一起使用的各种工作流程。

如果您刚刚开始并想尝试一下,启动iex并一次评估一个表达式是可行的方法。

iex(5)> Enum.reverse [1,2,3,4]
[4, 3, 2, 1]

您还可以在iex中获取有关Elixir模块和函数的帮助。大多数功能在他们的文档中都有示例。

iex(6)> h Enum.reverse

                        def reverse(collection)

Reverses the collection.
[...]

如果您想将一些代码放入文件中以便以后重复使用,推荐的(事实上的标准)方法是创建一个混合项目并开始向其添加模块。但也许,在依赖mix来执行常见任务(如编译代码,启动应用程序等)之前,您可能想知道在幕后发生了什么。让我解释一下。

将一些表达式放入文件并运行它的最简单方法是使用elixir命令。

x = :math.sqrt(1234)
IO.puts "Your square root is #{x}"

将上面的代码片段放入名为simple.exs的文件中,并使用elixir simple.exs运行它。 .exs扩展名只是一个约定,表示该文件是要评估的(这就是我们所做的)。

直到您想要开始构建项目为止。然后,您需要将代码组织到模块中。每个模块都是一组函数。它也是最小的编译单元:每个模块都被编译成.beam文件。通常人们每个源文件都有一个模块,但定义多个模块也可以。无论单个源文件中的模块数量如何,每个模块在编译时都将以其自己的.beam文件结束。

defmodule M do
  def hi(name) do
    IO.puts "Hello, #{name}"
  end
end

我们已经定义了一个具有单一功能的模块。将其保存到名为mymod.ex的文件中。我们可以通过多种方式使用它:

  • 启动iex并评估生成的shell会话中的代码:

    $ iex mymod.ex
    
    iex> M.hi "Alex"
    Hello, Alex
    :ok
    
  • 在运行其他代码之前对其进行评估。例如,要在命令行上评估单个表达式,请使用elixir -e <expr>。你可以&#34;要求&#34; (基本上,评估和加载)之前的一个或多个文件:

    $ elixir -r mymod.ex -e 'M.hi "Alex"'
    Hello, Alex
    
  • 编译它并让VM的代码加载工具找到它

    $ elixirc mymod.ex
    $ iex
    iex> M.hi "Alex"
    Hello, Alex
    :ok
    

在最后一个例子中,我们编译了在当前目录中生成名为Elixir.M.beam的文件的模块。然后,当您在同一目录中运行iex时,将在第一次调用其中的函数时加载该模块。您还可以使用其他方式来评估代码,例如elixir -e 'M.hi "..."'。只要代码加载器可以找到.beam文件,就会加载该模块并执行其中的相应功能。


然而,这完全是为了尝试使用一些代码示例。当您准备在Elixir中构建项目时,您将需要使用mixmix的工作流程或多或少如下:

$ mix new myproj
* creating README.md
* creating .gitignore
* creating mix.exs
[...]

$ cd myproj

# 'mix new' has generated a dummy test for you
# see test/myproj_test.exs
$ mix test

lib/目录中添加新模块。通常使用项目名称为所有模块名称添加前缀。因此,如果您使用我们上面定义的M模块并将其放入文件lib/m.ex中,它将如下所示:

 defmodule Myproj.M do
   def hi(name) do
     IO.puts "Hello, #{name}"
   end
 end

现在您可以在其中加载Mix项目的情况下启动shell。

 $ iex -S mix

运行上面的代码将编译所有源文件,并将它们放在_build目录下。 Mix还会为您设置代码路径,以便代码加载器可以在该目录中找到.beam个文件。

在混合项目的上下文中评估表达式如下所示:

$ mix run -e 'Myproj.M.hi "..."'

同样,不需要编译任何东西。大多数混音任务都会重新编译任何已更改的文件,因此您可以安全地假设您从中调用函数时已定义的任何模块都可用。

运行mix help查看所有可用任务,然后mix help <task>获取特定任务的详细说明。

答案 1 :(得分:9)

专门解决这个问题:

$ elixirc test.ex
如果文件定义了Elixir.Hello.beam模块,

将生成名为Hello的文件。

如果从包含此文件的目录运行elixiriex,该模块将可用。所以:

$ elixir -e Hello.some_function

$ iex

iex(1)> Hello.some_function

答案 2 :(得分:6)

假设我写了这样的Elixir程序:

defmodule PascalTriangle do
  defp next_row(m), do: for(x <- (-1..Map.size(m)-1), do: { (x+1), Map.get(m, x, 0) + Map.get(m, x+1, 0) } ) |> Map.new
  def draw(1), do: (IO.puts(1); %{ 0 => 1})
  def draw(n) do
    (new_map = draw(n - 1) |> next_row ) |> Map.values |> Enum.join(" ") |> IO.puts
    new_map
  end
end

模块PascalTriangle可以像这样使用:PascalTriangle.draw(8)

当您使用elixirc编译ex文件时,它将创建一个名为 Elixir.PascalTriangle.beam 的文件。

从命令行,您可以像这样执行beam文件: elixir -e "PascalTriangle.draw(8)"

您可以看到类似于照片的输出: enter image description here