Modules
Modules
In Elixir, we’ll be building modules to group related functions together.
We’ve already seen this in action when using previous modules, such as the String
.
Looking below we see the module String
has a function length
defined on it.
String.length("hello world")
We can create custom modules as well using the defmodule
macro.
Let’s say we want to create a Calc
module. We can define it like so:
iex> defmodule Calc do
end
The Calc
module isn’t very interesting yet. We can define functions inside a module using the def
keyword. Let’s define a double/1
.
iex> defmodule Calc do
def double(a) do
a + a
end
end
We can then call the Calc.double/0
function just like we are calling any other module:
iex> Calc.double(2) # 4
Let’s crate a file and write our code in there instead. Let’s create calc.ex
file
touch calc.ex
Now add the following code to the file.
defmodule Calc do
def double(a) do
a + a
end
end
Type each of the following lines into the command line - one line at a time.
iex
c("calc.ex")
Calc.double(4)
Once we open iex
we can use our c
function - which stands for compile. This will compile our calc.ex
file and allow us to access it inside of iex
.
Module Attributes
There is a way for us to create constants in modules
defmodule Calc do
@note "Fancy"
def desc() do
~s(#{@note} calculator.)
end
end
Structs
Structs are useful for handling known data structures.
They are extension built on top of maps. The keyword defstruct
defines what fields the struct will have along with their default values.
Structs take the name of the module they are defined in.
defmodule Calc.Op do
defstruct name: "add", a: 1, b: 1
end
We now have a Calc
struct %Calc{}
Stucts provide a compile-time guarantee that only the fields defined in defstruct
are allowed to exist in the struct.
Import
The import
command allows us to bring in functions from other modules
Let’s take a look at the following example:
iex(1)> import List
List
iex(2)> last([1, 2, 3])
3
iex(3)> import Enum, only: [map: 2]
Enum
iex(4)>
Note that last
is a function that is defined on List
. What other functions might we be able to access on list?
As we can see in the example -import
let’s us bring in a module, and then access any functions that are defined on that module.
Require
require
ensures a module is compiled and loaded in another module
Example:
defmodule Adder do
require Calc
def add(a, b) do
Calc.op({:add, a, b})
end
end
require
ensures that the entire Calc
module is compiled and loaded so that we can access it inside of Adder
.
Use
Injects Apis into modules
defmodule Calc do
defmacro __using__(_) do
quote do
def op({:add, a, b}), do: a + b
def op({:subtract, a, b}), do: a - b
def op(_) do
"Not implemented"
end
end
end
end
defmodule Adder do
use Calc
def add(a, b) do
op({:add, a, b})
end
end
It allows us to use functionality from certain modules inside of another module. Note that we can access the Calc
api inside of Adder
.
Next step:
Go on to Functions.
Or:
Go back to Pattern Matching.