a.exs:
defmodule A do
def greet, do: IO.puts "hello"
end
b.exs:
defmodule B do
import A
def say_hello, do: greet
end
结果:
~/elixir_programs$ iex b.exs
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
** (CompileError) b.exs:2: module A is not loaded and could not be found
~/elixir_programs$ tree .
.
├── a.exs
├── app1.exs
├── b.exs
....
为此,您如何使用限定名称来调用另一个模块中定义的函数:
b.exs:
defmodule B do
def say_hello, do: A.greet
end
~/elixir_programs$ iex b.exs
Erlang/OTP 20 [erts-9.3] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false]
Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> B.say_hello
** (UndefinedFunctionError) function A.greet/0 is undefined (module A is not available)
A.greet()
好的,这可行:
iex(1)> c "a.exs"
[A]
iex(2)> B.say_hello
hello
:ok
答案 0 :(得分:6)
关于Elixir,有两点需要理解:它是一种编译的语言,它区分编译文件和脚本(后者也可以编译,但默认情况下mix
不会自动编译。)
与脚本语言(ruby,python,javascript,...)不同,编译语言应该在功能可用之前经过两个阶段:应编译文件,然后然后运行时(阅读:Erlang VM)。一个人不能像我们在ruby中那样require 'foo'
,或者像在python中那样import bar
,并期望它能工作。
Elixir在Code
模块中提供了方便的助手来在运行时进行编译,包括但不限于:Code.require_file/2
和Code.compile_file/2
。
使用mix
时,默认情况下仅编译扩展名为.ex
的 non-script 文件。这就是为什么测试文件(即脚本(.exs
)永远不会与运行时混淆的原因。
也就是说,有四个主要选项可以使其起作用:
mix
项目和名为a.ex
和b.ex
的文件。这样一来,您就可以通过运行iex -S mix
来获取,编译所有内容。Code.require_file("a.exs")
中的b.exs
明确要求a.exs
。iex
告诉iex -r a.exs -r b.exs
进行编译(如果需要)并加载所有文件。答案 1 :(得分:1)
如果所有.exs
文件都在同一目录中,则可以运行iex -r *.exs
,这会将所有.exs
加载到您的iex会话中。您也可以通过iex -r a.exs -r b.exs
答案 2 :(得分:0)
这有效:
Interactive Elixir (1.6.6) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> c "a.exs"
[A]
iex(2)> c "b.exs"
[B]
iex(3)> B.say_hello
hello
:ok
iex(4)>
答案 3 :(得分:0)
您可以在终端中使用 elixrc(确保两个文件都在同一个文件夹中),如下所示:
elixirc a.exs b.exs
这将生成 .beam
文件。这些是 erlang VM 将运行的字节码文件。