Monday, January 30, 2017

Elixir - Modules

In Elixir we group several functions into modules. We’ve already used many different modules in the previous chapters such as the String module, Bitwise module, Tuple module, etc.
In order to create our own modules in Elixir, we use the defmodule macro. We use the def macro to define functions in that module:

defmodule Math do
    def sum(a, b) do
        a + b
    end
end
In the following sections, our examples are going to get longer in size, and it can be tricky to type them all in the shell. We need to learn how to compile Elixir code and also how to run Elixir scripts.

Compilation

Most of the time it is convenient to write modules into files so they can be compiled and reused. Let’s assume we have a file named math.ex with the following contents:
defmodule Math do
    def sum(a, b) do
        a + b
    end
end
We can compile the files using the command: elixirc:
$ elixirc math.ex
This will generate a file named Elixir.Math.beam containing the bytecode for the defined module. If we start iex again, our module definition will be available (provided that iex is started in the same directory the bytecode file is in). For example,
IO.puts(Math.sum(1, 2))
When running above program, it produces following result:
3

Scripted Mode

In addition to the Elixir file extension .ex, Elixir also supports .exs files for scripting. Elixir treats both files exactly the same way, the only difference is in intention. .ex files are meant to be compiled while .exs files are used for scripting. When executed, both extensions compile and load their modules into memory, although only .ex files write their bytecode to disk in the format of .beam files.
For example, if we wanted to run the Math.sum in the same file, we could use the .exs in following way:
Math.exs:
defmodule Math do
    def sum(a, b) do
        a + b
    end
end

IO.puts(Math.sum(1, 2))
We can run it using the elixir command:
$ elixir math.exs
The file will be compiled in memory and executed, printing “3” as the result. No bytecode file will be created.

Module Nesting

Modules can be nested in elixir. This feature of the language helps us better organize our code. To create nested modules, we use the following syntax:
defmodule Foo do
  #Foo module code here
  defmodule Bar do
    #Bar module code here
  end
end
The example above will define two modules: Foo and Foo.Bar. The second can be accessed as Bar inside Foo as long as they are in the same lexical scope. If, later, the Bar module is moved outside the Foo module definition, it must be referenced by its full name (Foo.Bar) or an alias must be set using the alias directive discussed in the alias chapter.
Note: in Elixir, you don’t have to define the Foo module before being able to define the Foo.Bar module, as the language translates all module names to atoms. You can define arbitrarily-nested modules without defining any module in the chain. For example Foo.Bar.Baz without defining Foo or Foo.Bar first).

No comments:

Post a Comment