Dx.Defd_ behaviour (dx v0.3.5)
View SourceUsed to make existing libraries compatible with Dx.Defd.
Defining functions
Define functions using defd_/2. The _ stands for basic or native.
defd_ functions are not recompiled by the Dx compiler.
They have to return either {:ok, result} or {:not_loaded, data_reqs}.
See Dx.Defd.Result for more information and Enum-like functions to work with results.
The input arguments can be a Dx.Scope struct or a Dx.Defd.Fn struct.
If you don't want to handle these internal structs, you can tell the compiler
to load/unwrap them by providing function information (see next section).
Function information
defmodule MyExt do
use Dx.Defd_
@dx_ args: [:preload_scope, :fn], warn_not_ok: "Be careful!"
defd_ map(enum, mapper) do
# ...
end
endOptions
args- list or map of argument indexes mapping to argument information- List format:
[:preload_scope, %{}, :fn]- each element maps to an argument position - Map format with special keys (highest to lowest precedence):
- Positive argument indexes (0..arity-1) counting from the first argument:
%{0 => :preload_scope} - Negative argument indexes (-1..-arity) counting from the last argument:
%{-1 => :preload_scope} :all- sets defaults for all arguments (explicitly defined or not)
- Positive argument indexes (0..arity-1) counting from the first argument:
- List format:
Argument information options:
:atom_to_scope- whether to wrap atoms inDx.Scope.all/1:preload_scope- tells the compiler to load any scopes passed via this argument:fn- tells the compiler to unwrap any Dx-specific function definitions{:fn, arity: 2, warn_not_ok: "Can't load data here"}- pass more information about the function:final_args_fn- likefnbut assumes that no scopes can be passed to the function in this argument{:final_args_fn, arity: 2, warn_always: "Don't use this function"}- pass more information about the function%{}or[]- placeholder for an argument without any special information
Additional options:
warn_not_ok- compiler warning to display when the function possibly loads datawarn_always- compiler warning to display when the function is used
Examples
defmodule MyExt do
use Dx.Defd_
# Using list format - positional arguments
@dx_ args: [:preload_scope, %{}, :final_args_fn]
defd_ my_function(scope, value, callback) do
# ...
end
# Using map format with positive and negative indexes
@dx_ args: %{0 => :preload_scope, -1 => :fn}, warn_not_ok: "Be careful!"
defd_ another_function(scope, value, callback) do
# ...
end
# Using :all to set defaults for all arguments
@dx_ args: %{all: :atom_to_scope, 0 => :preload_scope}
defd_ process_all(first, second, third) do
# first will be :preload_scope, all will have :atom_to_scope
end
endCompiler annotations & callbacks
There are three ways to provide function information for the Dx compiler:
- Using
@dx_module attributes before function definitions:
defmodule MyExt do
use Dx.Defd_
@dx_ args: [:preload_scope, %{}, :final_args_fn]
defd_ my_function(scope, value, callback) do
# ...
end
@dx_ args: %{0 => :preload_scope}, warn_not_ok: "Be careful!"
defd_ another_function(scope, value) do
# ...
end
endargs options will also be derived for functions with omitted default arguments.
- Using the
@moduledx_module attribute for module-wide defaults (can only be set once per module):
defmodule MyExt do
use Dx.Defd_
@moduledx_ args: %{all: :atom_to_scope},
warn_always: "This module is deprecated"
end- Implementing the
__dx_fun_info/2callback:
defmodule MyExt do
use Dx.Defd_
@impl true
def __dx_fun_info(fun_name, arity) do
%FunInfo{args: [:preload_scope, %{}, :final_args_fn]}
end
endAll three approaches can be combined. The precedence order (highest to lowest) is:
@dx_function-specific annotations
- merged into
@moduledx_defaults for that function
__dx_fun_info/2callback implementations
- always overrides
@moduledx_defaults
@moduledx_module-wide defaults
defmodule MyExt do
use Dx.Defd_
# Module-wide defaults (lowest precedence)
# Must be set once with all defaults
@moduledx_ args: %{all: :preload_scope},
warn_always: "Module under development"
# Function pattern in __dx_fun_info (middle precedence)
def __dx_fun_info(:special_case, 2) do
%FunInfo{args: [:preload_scope, :final_args_fn]}
end
# Function-specific override (highest precedence)
@dx_ args: [:preload_scope, :fn]
defd_ process_data(scope, callback) do
# This function's settings override both __dx_fun_info and @moduledx_
end
# Uses __dx_fun_info(:special_case, 2) settings
defd_ special_case(a, b) do
# ...
end
# Falls back to default @moduledx_ settings
defd_ other_function(x) do
# ...
end
end
Summary
Callbacks
@callback __dx_fun_info(atom(), non_neg_integer()) :: Dx.Defd_.FunInfo.input()
This callback is used to provide information about a function to Dx.Defd.