【发布时间】:2014-10-14 09:06:18
【问题描述】:
我已经安装了 Erlang/OTP 和 Elixir,并使用以下命令将 HelloWorld 程序编译成 BEAM:
elixirc test.ex
这产生了一个名为 Elixir.Hello.beam 的文件
如何运行这个文件?
【问题讨论】:
我已经安装了 Erlang/OTP 和 Elixir,并使用以下命令将 HelloWorld 程序编译成 BEAM:
elixirc test.ex
这产生了一个名为 Elixir.Hello.beam 的文件
如何运行这个文件?
【问题讨论】:
假设我这样写一个 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的文件。
从命令行,您可以像这样执行梁文件:
elixir -e "PascalTriangle.draw(8)"
【讨论】:
具体解决问题:
$ elixirc test.ex
如果文件定义了Hello 模块,将生成一个名为Elixir.Hello.beam 的文件。
如果您从包含此文件的目录运行elixir 或iex,则该模块将可用。所以:
$ elixir -e Hello.some_function
或
$ iex
iex(1)> Hello.some_function
【讨论】:
简答:如果不知道源文件的内容,就无法确定:)
有几种方法可以运行 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>。您可以在它之前“要求”(基本上是评估和加载)一个或多个文件:
$ 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 中构建项目时,您需要使用 mix。 mix 的工作流程大致如下:
$ 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> 可获取特定任务的详细说明。
【讨论】: