我安装了Erlang/OTP和Elixir,并使用以下命令将HelloWorld程序编译成BEAM:
elixirc test.ex
Run Code Online (Sandbox Code Playgroud)
其中生成了一个名为Elixir.Hello.beam的文件
我该如何运行这个文件?
Ale*_*lik 39
简短回答:没有办法知道你的源文件的内容:)
有几种方法可以运行Elixir代码.这个答案将概述可与Elixir一起使用的各种工作流程.
当您刚刚开始并想要尝试时,一次启动iex
和评估表达式是可行的方法.
iex(5)> Enum.reverse [1,2,3,4]
[4, 3, 2, 1]
Run Code Online (Sandbox Code Playgroud)
您还可以获得有关Elixir模块和功能的帮助iex
.大多数功能在他们的文档中都有示例.
iex(6)> h Enum.reverse
def reverse(collection)
Reverses the collection.
[...]
Run Code Online (Sandbox Code Playgroud)
当您想将一些代码放入文件以便以后重用时,推荐的(事实上的标准)方法是创建一个混合项目并开始向其添加模块.但也许,您想知道在依赖mix来执行常见任务(如编译代码,启动应用程序等)之前发生了什么.让我解释一下.
将一些表达式放入文件并运行它的最简单方法是使用该elixir
命令.
x = :math.sqrt(1234)
IO.puts "Your square root is #{x}"
Run Code Online (Sandbox Code Playgroud)
将上面的代码片段放入一个名为的文件中simple.exs
并运行它elixir simple.exs
.该.exs
扩展仅仅是一个约定,表明该文件是为了进行评估(这就是我们所做的事情).
这可以直到你想要开始构建项目为止.然后,您需要将代码组织到模块中.每个模块都是一组函数.它也是最小的编译单元:每个模块都被编译成一个.beam
文件.通常人们每个源文件都有一个模块,但定义多个模块也没问题.无论单个源文件中的模块数量如何,每个模块.beam
在编译时都将以其自己的文件结束.
defmodule M do
def hi(name) do
IO.puts "Hello, #{name}"
end
end
Run Code Online (Sandbox Code Playgroud)
我们已经定义了一个具有单一功能的模块.将其保存到名为的文件中mymod.ex
.我们可以通过多种方式使用它:
启动iex
并评估生成的shell会话中的代码:
$ iex mymod.ex
iex> M.hi "Alex"
Hello, Alex
:ok
Run Code Online (Sandbox Code Playgroud)在运行其他代码之前评估它.例如,要在命令行上计算单个表达式,请使用elixir -e <expr>
.您可以在其之前"需要"(基本上,评估和加载)一个或多个文件:
$ elixir -r mymod.ex -e 'M.hi "Alex"'
Hello, Alex
Run Code Online (Sandbox Code Playgroud)编译它,让VM的代码加载工具找到它
$ elixirc mymod.ex
$ iex
iex> M.hi "Alex"
Hello, Alex
:ok
Run Code Online (Sandbox Code Playgroud)在最后一个例子中,我们编译了生成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
Run Code Online (Sandbox Code Playgroud)
在lib/
目录中添加新模块.通常使用项目名称为所有模块名称添加前缀.因此,如果您使用M
我们上面定义的模块并将其放入文件中lib/m.ex
,它将如下所示:
defmodule Myproj.M do
def hi(name) do
IO.puts "Hello, #{name}"
end
end
Run Code Online (Sandbox Code Playgroud)
现在,您可以在其中加载Mix项目的情况下启动shell.
$ iex -S mix
Run Code Online (Sandbox Code Playgroud)
运行上面的代码将编译所有源文件,并将它们放在_build
目录下.Mix还会为您设置代码路径,以便代码加载器可以找到.beam
该目录中的文件.
在混合项目的上下文中评估表达式如下所示:
$ mix run -e 'Myproj.M.hi "..."'
Run Code Online (Sandbox Code Playgroud)
同样,不需要编译任何东西.大多数混合任务将重新编译任何已更改的文件,因此您可以安全地假设您从中调用函数时已定义的任何模块都可用.
运行mix help
以查看所有可用任务并mix help <task>
获取特定任务的详细说明.
Hen*_*k N 12
要专门解决这个问题:
$ elixirc test.ex
Run Code Online (Sandbox Code Playgroud)
Elixir.Hello.beam
如果文件定义了一个Hello
模块,将生成一个名为的文件.
如果您运行elixir
或iex
从包含此文件的目录运行,该模块将可用.所以:
$ elixir -e Hello.some_function
Run Code Online (Sandbox Code Playgroud)
要么
$ iex
iex(1)> Hello.some_function
Run Code Online (Sandbox Code Playgroud)
假设我写了一个像这样的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
Run Code Online (Sandbox Code Playgroud)
PascalTriangle模块可以像这样使用: PascalTriangle.draw(8)
当您使用elixirc
编译ex文件时,它将创建一个名为Elixir.PascalTriangle.beam的文件.
从命令行,您可以像这样执行beam文件:
elixir -e "PascalTriangle.draw(8)"