|
| 1 | +Resolving variables |
| 2 | +=================== |
| 3 | + |
| 4 | +In the original `JsonLogic`_ format, operators `accessing data <https://jsonlogic.com/operations.html#accessing-data>`_ |
| 5 | +use a dot-like notation. With the following expression: |
| 6 | + |
| 7 | +.. code-block:: json |
| 8 | +
|
| 9 | + {"var": "some.var"} |
| 10 | +
|
| 11 | +and the following data: |
| 12 | + |
| 13 | +.. code-block:: json |
| 14 | +
|
| 15 | + { |
| 16 | + "some": { |
| 17 | + "var": 1 |
| 18 | + } |
| 19 | + } |
| 20 | +
|
| 21 | +the expression will evaluate to :json:`1`. However, this dot-like notation can be ambiguous: |
| 22 | + |
| 23 | +- As the empty string :json:`""` is special cased to refer to the entire data object, it is impossible |
| 24 | + to refer to :json:`1` with the following data: |
| 25 | + |
| 26 | + .. code-block:: json |
| 27 | +
|
| 28 | + { |
| 29 | + "": 1 |
| 30 | + } |
| 31 | +
|
| 32 | + as the reference :json:`""` would evaluate to :json:`{"": 1}`, and :json:`"."` could be parsed as a reference to :json:`{"": {"": 1}}`. |
| 33 | + |
| 34 | +- There is no way to escape dots if present in data keys. The reference :json:`"some.var"` could refer to both |
| 35 | + :json:`1` and :json:`2` with the following data: |
| 36 | + |
| 37 | + .. code-block:: json |
| 38 | +
|
| 39 | + { |
| 40 | + "some": { |
| 41 | + "var": 1 |
| 42 | + }, |
| 43 | + "some.var": 2 |
| 44 | + } |
| 45 | +
|
| 46 | +For this reason, an alternative format is proposed, based on the JSON Pointer standard (:rfc:`6901`). The following expressions: |
| 47 | + |
| 48 | +with the following data: |
| 49 | + |
| 50 | +.. code-block:: json |
| 51 | +
|
| 52 | + { |
| 53 | + "path": 1, |
| 54 | + "": 2, |
| 55 | + "": {"": 3}, |
| 56 | + "path.to": 4, |
| 57 | + "path/": 5 |
| 58 | + } |
| 59 | +
|
| 60 | +this is how the references will evaluate: |
| 61 | + |
| 62 | +.. code-block:: bash |
| 63 | +
|
| 64 | + {"var": "/path"} -> 1 |
| 65 | + {"var": ""} -> 2 |
| 66 | + {"var": "/"} -> whole object |
| 67 | + {"var": "//"} -> 3 |
| 68 | + {"var": "/path.to"} -> 4 |
| 69 | + {"var": "/path~1"} -> 5 |
| 70 | +
|
| 71 | +Variables scopes |
| 72 | +---------------- |
| 73 | + |
| 74 | +The original `JsonLogic`_ format implicitly uses the notion scope in the implementation |
| 75 | +of some operators such as `map <https://jsonlogic.com/operations.html#map-reduce-and-filter>`_: |
| 76 | + |
| 77 | +.. code-block:: json |
| 78 | +
|
| 79 | + { |
| 80 | + "map": [ |
| 81 | + [1, 2], |
| 82 | + {"*": [{"var": ""}, 2]} |
| 83 | + ] |
| 84 | + } |
| 85 | +
|
| 86 | +In this case, the variable reference :json:`""` will refer to each element of the array :json:`[1, 2]`. |
| 87 | +This means that there is no way to access data from the top level object (say for example you wanted |
| 88 | +to multiply every element of the array with :json:`{"var": "some_const"}` instead of :json:`2`). |
| 89 | + |
| 90 | +The notion of *scope* is thus introduced, so that it is still possible to access data from the parent scope. |
| 91 | +This scope can be specified by appending ``@n`` at the end of the variable reference. The current scope starts at |
| 92 | +0, so using :json:`"some_var@0"` is equivalent to :json:`"some_var"`. |
| 93 | + |
| 94 | +Using our previous ``map`` example, with the following data: |
| 95 | + |
| 96 | +.. code-block:: json |
| 97 | +
|
| 98 | + { |
| 99 | + "some_const": 2 |
| 100 | + } |
| 101 | +
|
| 102 | +the operator can be written as: |
| 103 | + |
| 104 | +.. code-block:: json |
| 105 | +
|
| 106 | + { |
| 107 | + "map": [ |
| 108 | + [1, 2], |
| 109 | + {"*": [{"var": ""}, {"var": "some_const@1"}]} |
| 110 | + ] |
| 111 | + } |
| 112 | +
|
| 113 | +and would evaluate to :json:`[2, 4]`. |
| 114 | + |
| 115 | +For more details on resolving variables, you can refer to the API documentation: :doc:`../api/evaluation`. |
| 116 | + |
| 117 | +.. _`JsonLogic`: https://jsonlogic.com/ |
0 commit comments