View Source Code Execution
We can execute code in rules. This may be useful in the following scenarios:
- The output of a rule is not literal but should be calculated based on the input.
- One input field's value is based on another.
Currently (v0.1.0), we only support execution in output fields.
security-warning
Security WarningUse this feature with extreme caution! Never trust inputs from users.
syntax
Syntax
Code is wrapped in a "`" pair, e.g.
iex> table = Tablex.new("""
...> F x || abs
...> 1 >=0 || `x`
...> 2 <0 || `-x`
...> """)
...>
...> Tablex.decide(table, x: -42)
%{abs: 42}
restriction
Restriction
The code is in raw Elixir format but not all syntax tokens are allowed to use. It follows the default restriction of formular.
For example, the following code is not allowed:
MyApp.foo()
because it is not supported to invoke "." operation.
variables
Variables
We can refer to arbitary variable names as long as are provided in the binding argument of Tablex.decide/2
or Tablex/decide/3
. For example:
iex> table = Tablex.new("""
...> M day_of_week || "Go to Library" Volunteer Blogging
...> 1 1 || T - -
...> 2 2 || F T -
...> 3 - || F F `week_of_month == 4`
...> """)
...>
...> Tablex.decide(table, day_of_week: 1, week_of_month: 4)
%{go_to_library: true, volunteer: false, blogging: true}
Note that week_of_month
is not an input field but a bound variable on execution.
functions
Functions
Functions are supported through formular's custom function.
Example:
iex> defmodule MyFib do
...> @table Tablex.new("""
...> F x || fib
...> 1 0 || 0
...> 2 1 || 1
...> 3 >=2 || `fib(x - 1) + fib(x - 2)`
...> """)
...>
...> def fib(x) when is_integer(x) and x >= 0 do
...> %{fib: y} = Tablex.decide(@table, [x: x], context: __MODULE__)
...> y
...> end
...> end
...>
...> MyFib.fib(5)
5