plymio_codi v0.3.1 Plymio.Codi View Source
Plymio.Codi generates quoted forms for common code patterns.
The produce_codi/2 function produces the quoted forms for the
patterns.
The reify_codi/2 macro calls produce_codi/2 and then compiles
the forms.
Documentation Terms
In the documentation below these terms, usually in italics, are used to mean the same thing.
opts
opts is a Keyword list.
form and forms
A form is a quoted form (Macro.t). A forms is a list of zero, one or more forms.
vekil
The proxy patterns (see below) use a dictionary called the vekil: The proxy can be though of as the key while its value (called a from) “realises” to a form / forms.
The vekil implements the Plymio.Vekil protocol. If the vekil
given to new/1 or update/2 is a Map or Keyword, it will be
used to create a Plymio.Vekil.Form vekil.
The forom in the vekil must “realise”
(Plymio.Vekil.Forom.realise/2) to forms.
It is more efficient to pre-create (ideally at compile time) the
vekil; it can be edited later using e.g. :proxy_put.
Options (opts)
The first argument to both of these functions is an opts.
The canonical form of a pattern definition in the opts is the
key :pattern with an opts value specific to the
pattern e.g.
[pattern: [pattern: :delegate, name: :fun_one, arity: 1, module: ModuleA]
The value is referred to as the cpo below, short for codi pattern opts.
All pattern definitions are normalised to this format.
However, for convenience, the key can be the pattern name
(e.g. :delegate) and the value the (pre normalised) cpo:
[delegate: [name: :fun_one, arity: 1, module: ModuleA]
This example shows the code produced for the above:
iex> {:ok, {forms, _}} = [
...> delegate: [name: :fun_one, arity: 1, module: ModuleA],
...> ] |> produce_codi
...> forms |> harnais_helper_show_forms!
["@doc(\"Delegated to `ModuleA.fun_one/1`\")",
"defdelegate(fun_one(var1), to: ModuleA)"]
Also, again for convenience, some patterns will normalise the
value. For example the :doc pattern normalises this:
[doc: "This is a docstring"]
into this:
[pattern: [pattern: doc, doc: "This is a docstring"]
The keys in the cpo have aliases. Note the aliases are
pattern-specific. For examples :args is both an alias for
:spec_args and :fun_args. Each pattern below lists its keys’ aliases.
Common Codi Pattern Opts Keys
These are the keys that can appear in a cpo as well as the pattern-specific ones:
| Key | Aliases | Role |
|---|---|---|
:pattern | the name of the pattern | |
:forms_edit | :form_edit, :edit_forms, :edit_form | forms_edit/2 opts |
there are other, internal use, keys that can appear as well.
Editing Pattern Forms
Most patterns produce forms. Individual pattern forms can be edited by giving a :forms_edit key in the cpo
where the value is an opts understood by Plymio.Fontais.Form.forms_edit/2.
Alternatively the :forms_edit can be given in the opts to
produce_codi/2 (or reify_codi/2) and will be applied to all
produced forms.
Patterns
There are a number of patterns, some having aliases, described below:
| Pattern | Aliases |
|---|---|
:form | :forms, :ast, :asts |
:typespec_spec | :spec |
:doc | |
:since | |
:delegate | |
:delegate_module | |
:bang | |
:bang_module | |
:query | |
:query_module | |
:proxy_fetch | :proxy, :proxies, :proxies_fetch |
:proxy_put | :proxies_put |
:proxy_delete | :proxies_delete |
:proxy_get | :proxies_get |
:struct_get | |
:struct_fetch | |
:struct_put | |
:struct_maybe_put | |
:struct_has? | |
:struct_update | |
:struct_set | |
:struct_export |
Pattern: form
The form pattern is a convenience to embed arbitrary code.
See Plymio.Codi.Pattern.Other for details and examples.
Pattern: typespec_spec
The typespec_spec pattern builds a @spec module attribute form.
See Plymio.Codi.Pattern.Typespec for details and examples.
Pattern: doc
The doc pattern builds a @doc module attribute form.
See Plymio.Codi.Pattern.Doc for details and examples.
Pattern: since
The since pattern builds a @since module attribute form.
See Plymio.Codi.Pattern.Other for details and examples.
Pattern: deprecated
The deprecated pattern builds a @deprecated module attribute form.
See Plymio.Codi.Pattern.Other for details and examples.
Pattern: delegate and delegate_module
The delegate pattern builds a Kernel.defdelegate/2 call,
together, optionally, with a @doc, @since, and/or @spec.
The delegate_module pattern builds a Kernel.defdelegate/2 call
for one or more functions in a module. As with :delegate a @doc and/or @since
can be generated at the same time.
See Plymio.Codi.Pattern.Delegate for details and examples.
Pattern: bang and bang_module
The bang pattern builds bang functions
(e.g. myfun!(arg)) using existing base functions (e.g. myfun(arg)).
The bang_module pattern builds a bang function for one or more
functions in a module. As with :bang a @doc or @since can be generated at
the same time.
See Plymio.Codi.Pattern.Bang for details and examples.
Pattern: query and query_module
The query pattern works like bang but builds a query function
(e.g. myfun?(arg)) using a base function (e.g. myfun(arg)).
The query_module pattern builds a query function for one or more
functions in a module. As with :query a @doc or @since can be generated at
the same time.
See Plymio.Codi.Pattern.Query for details and examples.
Pattern: proxy patterns
The proxy patterns manage the vekil..
See Plymio.Codi.Pattern.Proxy for details and examples.
Pattern: struct patterns
The struct patterns create a range of transform functions for a module’s struct.
See Plymio.Codi.Pattern.Struct for details and examples.
Link to this section Summary
Link to this section Types
Link to this section Functions
new/1 creates a new instance of the module’s struct and, if the optional
opts were given, calls update/2 with the instance and the opts,
returning {:ok, instance}, else {:error, error}.
update/2 takes an instance of the module’s struct and an optional opts.
The opts are normalised by calling the module’s update_canonical_opts/1
and then reduced with update_field/2:
opts |> Enum.reduce(instance, fn {k,v}, s -> s |> update_field({k,v}) end)
{:ok, instance} is returned.