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
Result:
~/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
....
For that matter, how do you use the qualified name to call a function defined in another module:
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()
Okay, this works:
iex(1)> c "a.exs"
[A]
iex(2)> B.say_hello
hello
:ok
There are two main things one should understand about Elixir: it is a compiled language and it differentiates between compiled files and scripts (the latter are also compiled, but they do not compile automatically by mix
by default.)
Compiled languages, unlike scripting languages (ruby, python, javascript, ...) are supposed to pass two stages before the functionality becomes available: the files should be compiled and then the runtime (read: Erlang VM) should be loaded. One cannot just require 'foo'
as we do in ruby or import bar
as we do in python and expect the thing to work.
Elixir provides handy helpers to do a compilation in runtime in Code
module, including but not limited to: Code.require_file/2
and Code.compile_file/2
.
When using mix
, only the non-script files, having an extension .ex
, are compiled by default. That is why test files, being scripts (.exs
) do not ever mess up with the runtime.
That said, there are four main options to make it work:
mix
project and files named a.ex
and b.ex
. That way you’ll get everything on hand, compiled, by running iex -S mix
.Code.require_file("a.exs")
from your b.exs
to explicitly require a.exs
.iex
to compile (if necessary) and load all the files by running iex -r a.exs -r b.exs
.If all the .exs
files are in the same directory, you can run iex -r *.exs
and that will load all the .exs
into your iex session. You could also load the files one by one via iex -r a.exs -r b.exs
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With