plymio_codi v0.3.1 Plymio.Codi.Pattern.Query View Source
The query patterns build query functions
(e.g. myfun?(arg)) using existing base functions (e.g. myfun(arg)).
When the base function returns {:ok, value}, the query
function returns true. Otherwise false is returned.
Query functions can be built with, optionally, with a @doc, @since
and/or @spec.
See Plymio.Codi for an overview and documentation terms.
Note if the base function is in another module, the base mfa
{module, function, arity} is validated i.e. the function must
exist in the module with the given arity.
If :fun_doc is not in the pattern opts, a default of :query is
used. (It can be disabled by explicitly setting :fun_doc to
nil)
Pattern: query
Valid keys in the cpo are:
| Key | Aliases |
|---|---|
:query_module | :module, :fun_mod, :query_module, :function_module |
:query_name | :name, :fun_name, :function_name |
:query_args | :args, :fun_args, :function_args |
:query_arity | :arity, :fun_arity, :function_arity |
:query_doc | :doc, :fun_doc, :function_doc |
:typespec_spec_spec_args | :spec_args |
:typespec_spec_result | ::result, :spec_result, :fun_result, :function_result |
:since |
Examples
Here is the common case of a query function for a function in the
same module. Note the automatically generated :query-format @doc
and explicitly specified @since:
iex> {:ok, {forms, _}} = [
...> query: [as: :fun_tre, arity: 3, since: "1.7.9"]
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `fun_tre/3`\"",
"@since \"1.7.9\"",
"def(fun_tre?(var1, var2, var3)) do",
" case(fun_tre(var1, var2, var3)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end"]
Here the other function is in a different module(ModuleA):
iex> {:ok, {forms, _}} = [
...> query: [as: :fun_tre, arity: 3, to: ModuleA, since: "1.7.9"]
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `ModuleA.fun_tre/3`\"",
"@since \"1.7.9\"",
"def(fun_tre?(var1, var2, var3)) do",
" case(ModuleA.fun_tre(var1, var2, var3)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end"]
The :fun_args can be supplied to improve the definition. Note the
:fun_doc is set to false.
iex> {:ok, {forms, _}} = [
...> query: [as: :fun_tre, args: [:x, :y, :z], to: ModuleA, fun_doc: false]
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc false",
"def(fun_tre?(x, y, z)) do",
" case(ModuleA.fun_tre(x, y, z)) do",
" {:ok, _} ->",
" true", "",
" _ ->",
" false",
" end",
"end"]
Similary, if the cpo contains a :spec_result key, a @spec will
be generated. The second example has an explicit :spec_args
note the @spec result is always boolean and any given value will be ignored.
iex> {:ok, {forms, _}} = [
...> query: [as: :fun_tre, args: [:x, :y, :z], module: ModuleA, result: true]
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `ModuleA.fun_tre/3`\"",
"@spec fun_tre?(any, any, any) :: boolean",
"def(fun_tre?(x, y, z)) do",
" case(ModuleA.fun_tre(x, y, z)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end"]
iex> {:ok, {forms, _}} = [
...> query: [as: :fun_tre, args: [:x, :y, :z], module: ModuleA,
...> spec_args: [:integer, :binary, :atom], result: :tuple]
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `ModuleA.fun_tre/3`\"",
"@spec fun_tre?(integer, binary, atom) :: boolean",
"def(fun_tre?(x, y, z)) do",
" case(ModuleA.fun_tre(x, y, z)) do",
" {:ok, _} ->",
" true", "",
" _ ->",
" false",
" end",
"end"]
Pattern: query_module
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.
Valid keys in the cpo are:
| Key | Aliases |
|---|---|
:query_module | :to, :module, :fun_mod, :fun_module, :function_module |
:query_doc | :doc, :fun_doc, :function_doc |
:take | |
:drop | |
:filter | |
:reject | |
:since |
Examples
Here a query function will be generated for all the functions in the module.
iex> {:ok, {forms, _}} = [
...> query_module: [module: ModuleA],
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `ModuleA.fun_due/2`\"",
"def(fun_due?(var1, var2)) do",
" case(ModuleA.fun_due(var1, var2)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end",
"@doc \"Query function for `ModuleA.fun_one/1`\"",
"def(fun_one?(var1)) do", " case(ModuleA.fun_one(var1)) do",
" {:ok, _} ->",
" true",
"", " _ ->", " false",
" end", "end", "@doc \"Query function for `ModuleA.fun_tre/3`\"",
"def(fun_tre?(var1, var2, var3)) do",
" case(ModuleA.fun_tre(var1, var2, var3)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end"]
In the same way as :bang_module the functions can be selected
using e.g. :take. Here :since is also given.
iex> {:ok, {forms, _}} = [
...> query_module: [module: ModuleA, take: :fun_due, since: "1.7.9"],
...> ] |> produce_codi
...> forms |> harnais_helper_format_forms!
["@doc \"Query function for `ModuleA.fun_due/2`\"",
"@since \"1.7.9\"",
"def(fun_due?(var1, var2)) do",
" case(ModuleA.fun_due(var1, var2)) do",
" {:ok, _} ->",
" true",
"",
" _ ->",
" false",
" end",
"end"]