如何导入在另一个文件中定义的自定义模块?

问题描述 投票:0回答:5

a.ex:

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
elixir
5个回答
19
投票

关于 Elixir,我们应该了解两件主要的事情:它是一种编译语言,它区分编译文件脚本(后者也是编译的,但默认情况下它们不会被

mix
自动编译) .)

与脚本语言(ruby,python,javascript,...)不同,编译语言在功能可用之前应该经过两个阶段:应该编译文件,然后应该加载运行时(阅读:Erlang VM) 。人们不能像我们在 ruby 中所做的那样 require 'foo'

 或像我们在 python 中那样 
import bar
 并期望它能够工作。

Elixir 提供了方便的助手来在

Code

 模块中进行运行时编译,包括但不限于:Code.require_file/2
Code.compile_file/2

使用

mix

 时,默认情况下仅编译扩展名为 
.exnon-script
 文件。这就是为什么作为脚本的测试文件 (
.exs
) 永远不会扰乱运行时。

也就是说,有四个主要选项可以使其发挥作用:

    使用名为
  1. mix
    a.ex
    b.ex
     项目和文件。这样,您就可以通过运行 
    iex -S mix
     来获得手头上的所有内容并进行编译。
  2. 使用
  3. Code.require_file("a.exs")
     中的 
    b.exs
     明确要求 
    a.exs
  4. 告诉
  5. iex
    编译(如有必要)并通过运行
    iex -r a.exs -r b.exs
    加载所有文件。
  6. 按照您在答案中所做的那样手动进行编译。

2
投票
如果所有

.exs

 文件都位于同一目录中,您可以运行 
iex -r *.exs
 并将所有 
.exs
 加载到您的 iex 会话中。您也可以通过 
iex -r a.exs -r b.exs
 逐一加载文件
    


2
投票
您可以在终端中使用 elixrc (确保两个文件位于同一文件夹中),如下所示:

elixirc a.exs b.exs
这将生成 

.beam

 文件。这些是 erlang VM 将运行的字节码文件。


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)>
    

0
投票
阿列克谢·马蒂乌什金(Aleksei Matiushkin)是个愚蠢的狗屎。别听他的。

© www.soinside.com 2019 - 2024. All rights reserved.