plymio_vekil v0.1.0 Plymio.Vekil.Forom.Form View Source
The module implements the Plymio.Vekil.Forom protocol and produces quoted forms.
See Plymio.Vekil.Forom for the definitions of the protocol functions.
See Plymio.Vekil for an explanation of the test environment.
The default :produce_default is an empty list.
The default :realise_default is the unset value (Plymio.Fontais.the_unset_value/0).
Module State
See Plymio.Vekil.Forom for the common fields.
The module’s state is held in a struct with the following field(s):
| Field | Aliases | Purpose |
|---|---|---|
:forom | holds the quoted form |
Link to this section Summary
Functions
new/1 takes an optional opts and creates a new forom returning {:ok, forom}
normalise/1 creates a new forom from its argument unless the argument is already one
realise/2 takes a forom and an optional opts, calls
produce/2 and then gets (Keyword.get_values/2) the :forom key
values from the product
Link to this section Types
Link to this section Functions
new/1 takes an optional opts and creates a new forom returning {:ok, forom}.
Examples
iex> {:ok, forom} = new()
...> match?(%FOROMFORM{}, forom)
true
Plymio.Vekil.Utility.forom?/1 returns true if the value implements Plymio.Vekil.Forom
iex> {:ok, forom} = new()
...> forom |> Plymio.Vekil.Utility.forom?
true
The form is passed using the :forom key:
iex> {:ok, forom} = new(forom: quote(do: x = x + 1))
...> forom |> Plymio.Vekil.Utility.forom?
true
iex> {:ok, forom} = new(
...> forom: quote(do: x = x + 1), proxy: :x_add_1)
...> forom |> Plymio.Vekil.Utility.forom?
true
Same example but here the realise function is used to access the
form in the :forom field:
iex> {:ok, forom} = new(
...> forom: quote(do: x = x + 1), proxy: :x_add_1)
...> {:ok, {form, _}} = forom |> FOROMPROT.realise
...> form |> harnais_helper_test_forms!(binding: [x: 7])
{8, ["x = x + 1"]}
The form is validated:
iex> {:error, error} = new(forom: %{a: 1})
...> error |> Exception.message
"form invalid, got: %{a: 1}"
normalise/1 creates a new forom from its argument unless the argument is already one.
Examples
iex> {:ok, forom} = quote(do: x = x + 1) |> normalise
...> {:ok, {form, _}} = forom |> FOROMPROT.realise
...> form |> harnais_helper_test_forms!(binding: [x: 3])
{4, ["x = x + 1"]}
iex> {:ok, forom} = normalise(
...> forom: quote(do: x = x + 1), proxy: :add_1)
...> {:ok, {form, _}} = forom |> FOROMPROT.realise
...> form |> harnais_helper_test_forms!(binding: [x: 3])
{4, ["x = x + 1"]}
Multiples forms can be stored:
iex> {:ok, forom} = [
...> quote(do: x = x + 1),
...> quote(do: x = x * x),
...> quote(do: x = x - 1)
...> ] |> normalise
...> {:ok, {forms, _}} = forom |> FOROMPROT.realise
...> forms |> harnais_helper_test_forms!(binding: [x: 3])
{15, ["x = x + 1", "x = x * x", "x = x - 1"]}
An invalid form returns an error result:
iex> {:error, error} = %{a: 1} |> normalise
...> error |> Exception.message
"form invalid, got: %{a: 1}"
An existing forom (of any implementation) is returned unchanged:
iex> {:ok, forom} = quote(do: x = x + 1) |> normalise
...> {:ok, forom} = forom |> normalise
...> {:ok, {form, _}} = forom |> FOROMPROT.realise
...> form |> harnais_helper_test_forms!(binding: [x: 8])
{9, ["x = x + 1"]}
produce/2 takes a forom and an optional opts, calls update/2
with the vekil and the opts if any, and returns {:ok, {product, forom}}.
The product will be Keyword with one or more :forom keys where the values are the forms.
Examples
iex> {:ok, forom} = quote(do: x = x + 1) |> normalise
...> {:ok, {product, %FOROMFORM{}}} = forom |> FOROMPROT.produce
...> [:forom] = product |> Keyword.keys |> Enum.uniq
...> product |> Keyword.get_values(:forom)
...> |> harnais_helper_test_forms!(binding: [x: 41])
{42, ["x = x + 1"]}
iex> {:ok, forom} = [
...> quote(do: x = x + 1),
...> quote(do: x = x * x),
...> quote(do: x = x - 1)
...> ] |> normalise
...> {:ok, {product, _}} = forom |> FOROMPROT.produce
...> product |> Keyword.get_values(:forom)
...> |> harnais_helper_test_forms!(binding: [x: 3])
{15, ["[x = x + 1, x = x * x, x = x - 1]"]}
If opts are given, update/2 is called before producing the forom:
iex> {:ok, forom} = new()
...> {:ok, forom} = forom |> update(forom: quote(do: x = x + 1))
...> {:ok, {product, %FOROMFORM{}}} = forom |> FOROMPROT.produce
...> [:forom] = product |> Keyword.keys |> Enum.uniq
...> product |> Keyword.get_values(:forom)
...> |> harnais_helper_test_forms!(binding: [x: 41])
{42, ["x = x + 1"]}
An empty forom does not produce any :forom keys:
iex> {:ok, forom} = new()
...> {:ok, {product, _}} = forom |> FOROMPROT.produce
...> product |> Keyword.get_values(:forom)
...> |> harnais_helper_test_forms!(binding: [x: 41])
{nil, []}
realise/2 takes a forom and an optional opts, calls
produce/2 and then gets (Keyword.get_values/2) the :forom key
values from the product.
The forms are then normalised
(Plymio.Fontais.Form.forms_normalise/1) and {:ok, {forms, forom}} returned.
Examples
iex> {:ok, forom} = quote(do: x = x + 1) |> normalise
...> {:ok, {forms, _}} = forom |> FOROMPROT.realise
...> forms |> harnais_helper_test_forms!(binding: [x: 41])
{42, ["x = x + 1"]}
iex> {:ok, forom} = [
...> quote(do: x = x + 1),
...> quote(do: x = x * x),
...> quote(do: x = x - 1)
...> ] |> normalise
...> {:ok, {forms, %FOROMFORM{}}} = forom |> FOROMPROT.realise
...> forms |> harnais_helper_test_forms!(binding: [x: 3])
{15, ["x = x + 1", "x = x * x", "x = x - 1"]}
If opts are given, update/2 is called before realising the forom:
iex> {:ok, forom} = new()
...> {:ok, {forms, %FOROMFORM{}}} = forom
...> |> FOROMPROT.realise(forom: quote(do: x = x + 1))
...> forms |> harnais_helper_test_forms!(binding: [x: 41])
{42, ["x = x + 1"]}
An empty forom does not produce any :forom keys so the :realise_default is returned:
iex> {:ok, forom} = new()
...> {:ok, {value, _forom}} = forom |> FOROMPROT.realise
...> value |> Plymio.Fontais.Guard.is_value_unset
true
update/2 implements Plymio.Vekil.Forom.update/2.
Examples
iex> {:ok, forom} = new(
...> forom: quote(do: x = x + 1), proxy: :x_add_1)
...> {:ok, forom} = forom |> update(forom: quote(do: x = x * x))
...> {:ok, {form, _}} = forom |> FOROMPROT.realise
...> form |> harnais_helper_test_forms!(binding: [x: 7])
{49, ["x = x * x"]}