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.