On this page
Code
Utilities for managing code compilation, code evaluation and code loading.
This module complements Erlang’s :code
module to add behaviour which is specific to Elixir. Almost all of the functions in this module have global side effects on the behaviour of Elixir.
Summary
Functions
- append_path(path)
-
Appends a path to the end of the Erlang VM code path list
- available_compiler_options()
-
Returns a list with the available compiler options
- compile_quoted(quoted, file \\ "nofile")
-
Compiles the quoted expression
- compile_string(string, file \\ "nofile")
-
Compiles the given string
- compiler_options()
-
Gets the compilation options from the code server
- compiler_options(opts)
-
Sets compilation options
- delete_path(path)
-
Deletes a path from the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code
- ensure_compiled(module)
-
Ensures the given module is compiled and loaded
- ensure_compiled?(module)
-
Ensures the given module is compiled and loaded
- ensure_loaded(module)
-
Ensures the given module is loaded
- ensure_loaded?(module)
-
Ensures the given module is loaded
- eval_file(file, relative_to \\ nil)
-
Evals the given file
- eval_quoted(quoted, binding \\ [], opts \\ [])
-
Evaluates the quoted contents
- eval_string(string, binding \\ [], opts \\ [])
-
Evaluates the contents given by
string
- get_docs(module, kind)
-
Returns the docs for the given module
- load_file(file, relative_to \\ nil)
-
Loads the given file
- loaded_files()
-
Lists all loaded files
- prepend_path(path)
-
Prepends a path to the beginning of the Erlang VM code path list
- require_file(file, relative_to \\ nil)
-
Requires the given
file
- string_to_quoted(string, opts \\ [])
-
Converts the given string to its quoted form
- string_to_quoted!(string, opts \\ [])
-
Converts the given string to its quoted form
- unload_files(files)
-
Removes files from the loaded files list
Functions
append_path(path)
Appends a path to the end of the Erlang VM code path list.
This is the list of directories the Erlang VM uses for finding module code.
The path is expanded with Path.expand/1
before being appended. If this path does not exist, an error is returned.
Examples
Code.append_path(".") #=> true
Code.append_path("/does_not_exist") #=> {:error, :bad_directory}
available_compiler_options()
Returns a list with the available compiler options.
See Code.compiler_options/1
for more info.
Examples
iex> Code.available_compiler_options
[:docs, :debug_info, :ignore_module_conflict, :relative_paths, :warnings_as_errors]
compile_quoted(quoted, file \\ "nofile")
Compiles the quoted expression.
Returns a list of tuples where the first element is the module name and the second one is its byte code (as a binary).
compile_string(string, file \\ "nofile")
Compiles the given string.
Returns a list of tuples where the first element is the module name and the second one is its byte code (as a binary).
For compiling many files at once, check Kernel.ParallelCompiler.files/2
.
compiler_options()
Gets the compilation options from the code server.
Check compiler_options/1
for more information.
Examples
Code.compiler_options
#=> %{debug_info: true, docs: true,
warnings_as_errors: false, ignore_module_conflict: false}
compiler_options(opts)
Sets compilation options.
These options are global since they are stored by Elixir’s Code Server.
Available options are:
:docs
- whentrue
, retain documentation in the compiled module,true
by default:debug_info
- whentrue
, retain debug information in the compiled module; this allows a developer to reconstruct the original source code,false
by default:ignore_module_conflict
- whentrue
, override modules that were already defined without raising errors,false
by default:relative_paths
- whentrue
, use relative paths in quoted nodes, warnings and errors generated by the compiler,true
by default. Note disabling this option won’t affect runtime warnings and errors.:warnings_as_errors
- causes compilation to fail when warnings are generated
It returns the new list of compiler options.
Examples
Code.compiler_options(debug_info: true)
#=> %{debug_info: true, docs: true,
warnings_as_errors: false, ignore_module_conflict: false}
delete_path(path)
Deletes a path from the Erlang VM code path list. This is the list of directories the Erlang VM uses for finding module code.
The path is expanded with Path.expand/1
before being deleted. If the path does not exist it returns false
.
Examples
Code.prepend_path(".")
Code.delete_path(".") #=> true
Code.delete_path("/does_not_exist") #=> false
ensure_compiled(module)
ensure_compiled(module()) ::
{:module, module()} |
{:error, :embedded | :badfile | :nofile | :on_load_failure}
Ensures the given module is compiled and loaded.
If the module is already loaded, it works as no-op. If the module was not loaded yet, it checks if it needs to be compiled first and then tries to load it.
If it succeeds loading the module, it returns {:module, module}
. If not, returns {:error, reason}
with the error reason.
Check ensure_loaded/1
for more information on module loading and when to use ensure_loaded/1
or ensure_compiled/1
.
ensure_compiled?(module)
ensure_compiled?(module()) :: boolean()
Ensures the given module is compiled and loaded.
Similar to ensure_compiled/1
, but returns true
if the module is already loaded or was successfully loaded and compiled. Returns false
otherwise.
ensure_loaded(module)
ensure_loaded(module()) ::
{:module, module()} |
{:error, :embedded | :badfile | :nofile | :on_load_failure}
Ensures the given module is loaded.
If the module is already loaded, this works as no-op. If the module was not yet loaded, it tries to load it.
If it succeeds loading the module, it returns {:module, module}
. If not, returns {:error, reason}
with the error reason.
Code loading on the Erlang VM
Erlang has two modes to load code: interactive and embedded.
By default, the Erlang VM runs in interactive mode, where modules are loaded as needed. In embedded mode the opposite happens, as all modules need to be loaded upfront or explicitly.
Therefore, this function is used to check if a module is loaded before using it and allows one to react accordingly. For example, the URI
module uses this function to check if a specific parser exists for a given URI scheme.
Code.ensure_compiled/1
Elixir also contains an ensure_compiled/1
function that is a superset of ensure_loaded/1
.
Since Elixir’s compilation happens in parallel, in some situations you may need to use a module that was not yet compiled, therefore it can’t even be loaded.
ensure_compiled/1
halts the current process until the module we are depending on is available.
In most cases, ensure_loaded/1
is enough. ensure_compiled/1
must be used in rare cases, usually involving macros that need to invoke a module for callback information.
Examples
iex> Code.ensure_loaded(Atom)
{:module, Atom}
iex> Code.ensure_loaded(DoesNotExist)
{:error, :nofile}
ensure_loaded?(module)
Ensures the given module is loaded.
Similar to ensure_loaded/1
, but returns true
if the module is already loaded or was successfully loaded. Returns false
otherwise.
Examples
iex> Code.ensure_loaded?(Atom)
true
eval_file(file, relative_to \\ nil)
Evals the given file.
Accepts relative_to
as an argument to tell where the file is located.
While load_file
loads a file and returns the loaded modules and their byte code, eval_file
simply evaluates the file contents and returns the evaluation result and its bindings.
eval_quoted(quoted, binding \\ [], opts \\ [])
Evaluates the quoted contents.
Warning: Calling this function inside a macro is considered bad practice as it will attempt to evaluate runtime values at compile time. Macro arguments are typically transformed by unquoting them into the returned quoted expressions (instead of evaluated).
See eval_string/3
for a description of bindings and options.
Examples
iex> contents = quote(do: var!(a) + var!(b))
iex> Code.eval_quoted(contents, [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line)
{3, [a: 1, b: 2]}
For convenience, you can pass __ENV__/0
as the opts
argument and all options will be automatically extracted from the current environment:
iex> contents = quote(do: var!(a) + var!(b))
iex> Code.eval_quoted(contents, [a: 1, b: 2], __ENV__)
{3, [a: 1, b: 2]}
eval_string(string, binding \\ [], opts \\ [])
Evaluates the contents given by string
.
The binding
argument is a keyword list of variable bindings. The opts
argument is a keyword list of environment options.
Options
Options can be:
:file
- the file to be considered in the evaluation:line
- the line on which the script starts
Additionally, the following scope values can be configured:
:aliases
- a list of tuples with the alias and its target:requires
- a list of modules required:functions
- a list of tuples where the first element is a module and the second a list of imported function names and arity; the list of function names and arity must be sorted:macros
- a list of tuples where the first element is a module and the second a list of imported macro names and arity; the list of function names and arity must be sorted
Notice that setting any of the values above overrides Elixir’s default values. For example, setting :requires
to []
, will no longer automatically require the Kernel
module; in the same way setting :macros
will no longer auto-import Kernel
macros like if/2
, case/2
, etc.
Returns a tuple of the form {value, binding}
, where value
is the value returned from evaluating string
. If an error occurs while evaluating string
an exception will be raised.
binding
is a keyword list with the value of all variable bindings after evaluating string
. The binding key is usually an atom, but it may be a tuple for variables defined in a different context.
Examples
iex> Code.eval_string("a + b", [a: 1, b: 2], file: __ENV__.file, line: __ENV__.line)
{3, [a: 1, b: 2]}
iex> Code.eval_string("c = a + b", [a: 1, b: 2], __ENV__)
{3, [a: 1, b: 2, c: 3]}
iex> Code.eval_string("a = a + b", [a: 1, b: 2])
{3, [a: 3, b: 2]}
For convenience, you can pass __ENV__/0
as the opts
argument and all imports, requires and aliases defined in the current environment will be automatically carried over:
iex> Code.eval_string("a + b", [a: 1, b: 2], __ENV__)
{3, [a: 1, b: 2]}
get_docs(module, kind)
Returns the docs for the given module.
When given a module name, it finds its BEAM code and reads the docs from it.
When given a path to a .beam file, it will load the docs directly from that file.
The return value depends on the kind
value:
:docs
- list of all docstrings attached to functions and macros using the@doc
attribute:moduledoc
- tuple{<line>, <doc>}
whereline
is the line on which module definition starts anddoc
is the string attached to the module using the@moduledoc
attribute:callback_docs
- list of all docstrings attached to@callbacks
using the@doc
attribute:type_docs
- list of all docstrings attached to@type
callbacks using the@typedoc
attribute:all
- a keyword list with:docs
and:moduledoc
,:callback_docs
, and:type_docs
.
If the module cannot be found, it returns nil
.
Examples
# Get the module documentation
iex> {_line, text} = Code.get_docs(Atom, :moduledoc)
iex> String.split(text, "\n") |> Enum.at(0)
"Convenience functions for working with atoms."
# Module doesn't exist
iex> Code.get_docs(ModuleNotGood, :all)
nil
load_file(file, relative_to \\ nil)
Loads the given file.
Accepts relative_to
as an argument to tell where the file is located. If the file was already required/loaded, loads it again.
It returns a list of tuples {ModuleName, <<byte_code>>}
, one tuple for each module defined in the file.
Notice that if load_file
is invoked by different processes concurrently, the target file will be loaded concurrently many times. Check require_file/2
if you don’t want a file to be loaded concurrently.
Examples
Code.load_file("eex_test.exs", "../eex/test") |> List.first
#=> {EExTest.Compiled, <<70, 79, 82, 49, ...>>}
loaded_files()
Lists all loaded files.
Examples
Code.require_file("../eex/test/eex_test.exs")
List.first(Code.loaded_files) =~ "eex_test.exs" #=> true
prepend_path(path)
Prepends a path to the beginning of the Erlang VM code path list.
This is the list of directories the Erlang VM uses for finding module code.
The path is expanded with Path.expand/1
before being prepended. If this path does not exist, an error is returned.
Examples
Code.prepend_path(".") #=> true
Code.prepend_path("/does_not_exist") #=> {:error, :bad_directory}
require_file(file, relative_to \\ nil)
Requires the given file
.
Accepts relative_to
as an argument to tell where the file is located. The return value is the same as that of load_file/2
. If the file was already required/loaded, doesn’t do anything and returns nil
.
Notice that if require_file
is invoked by different processes concurrently, the first process to invoke require_file
acquires a lock and the remaining ones will block until the file is available. I.e. if require_file
is called N times with a given file, it will be loaded only once. The first process to call require_file
will get the list of loaded modules, others will get nil
.
Check load_file/2
if you want a file to be loaded multiple times. See also unload_files/1
Examples
If the code is already loaded, it returns nil
:
Code.require_file("eex_test.exs", "../eex/test") #=> nil
If the code is not loaded yet, it returns the same as load_file/2
:
Code.require_file("eex_test.exs", "../eex/test") |> List.first
#=> {EExTest.Compiled, <<70, 79, 82, 49, ...>>}
string_to_quoted(string, opts \\ [])
Converts the given string to its quoted form.
Returns {:ok, quoted_form}
if it succeeds, {:error, {line, error, token}}
otherwise.
Options
:file
- the filename to be used in stacktraces and the file reported in the__ENV__/0
macro:line
- the line reported in the__ENV__/0
macro:existing_atoms_only
- whentrue
, raises an error when non-existing atoms are found by the tokenizer
Macro.to_string/2
The opposite of converting a string to its quoted form is Macro.to_string/2
, which converts a quoted form to a string/binary representation.
string_to_quoted!(string, opts \\ [])
Converts the given string to its quoted form.
It returns the ast if it succeeds, raises an exception otherwise. The exception is a TokenMissingError
in case a token is missing (usually because the expression is incomplete), SyntaxError
otherwise.
Check string_to_quoted/2
for options information.
unload_files(files)
Removes files from the loaded files list.
The modules defined in the file are not removed; calling this function only removes them from the list, allowing them to be required again.
Examples
# Load EEx test code, unload file, check for functions still available
Code.load_file("../eex/test/eex_test.exs")
Code.unload_files(Code.loaded_files)
function_exported?(EExTest.Compiled, :before_compile, 0) #=> true
© 2012 Plataformatec
Licensed under the Apache License, Version 2.0.
https://hexdocs.pm/elixir/1.4.5/Code.html