.. _redefine:

Redefine a variable
===================

We have already introduced the concept of :ref:`variable mutability <variable_mutability>`.
To summarize, an :term:`integrator` allows the :ref:`structured data <structured_data>` to evolve at any time.

.. glossary::

   redefine

      A redefine is a redefinition of all or part of the parameters of a variable or a family as it was previously defined.

.. note::

   Adding a variable to a family is not considered redefining the family. This is implicitly permitted. Redefining a family requires modifying one or more of its parameters.

.. seealso::

   See the tutorial with a real world sample :ref:`redefine <tutorial_redefine>`.

Explicit redefine
~~~~~~~~~~~~~~~~~

The redefinition is explicit.
This means that if an :term:`integrator` defines the same tree twice for two variables, Rougail will consider that there is a naming conflict.

To illustrate, we could create two :term:`structure files <structure file>`:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1

    my_variable:  # A description
    ...

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1

    my_variable:  # A redefined description
    ...

And the name conflict is detected:

.. code-block:: bash
   :class: terminal 

   $ rougail -m variable.yml redefine.yml
   ERROR: variable "my_variable" define multiple time in "variable.yml" and "redefine.yml"

So we have to explicit redefine a variable like this:

.. code-block:: yaml

   %YAML 1.2
   ---
   version: 1.1
   
   my_variable:
     redefine: true
     description: A redefined description
   ...

Now we can see that the redefinition is correct:

.. code-block:: bash
   :class: terminal 

    $rougail -m variable.yml redefine.yml -o doc
    ┏━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━┓
    ┃ Variable            ┃ Description              ┃
    ┡━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━┩
    │ my_variable         │ A redefined description. │
    │  string   mandatory │                          │
    └─────────────────────┴──────────────────────────┘

The new description has been taken into account.

Unify
~~~~~

When redefining a variable, we define the list of parameters that we wish to redefine.

In other words the variable is unify (combine) from multiple variables declarations.

The old parameters that were present before the redefinition are still present.

If we modify the `redefine.yml` :term:`structure file`:

.. code-block:: yaml

    %YAML 1.2
    ---
    version: 1.1
    
    my_variable:
      redefine: true
      type: integer
    ...

.. code-block:: bash
   :class: terminal 

   $ rougail -m variable.yml redefine.yml -o doc
   ┏━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━┓
   ┃ Variable             ┃ Description    ┃
   ┡━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━┩
   │ my_variable          │ A description. │
   │  integer   mandatory │                │
   └──────────────────────┴────────────────┘

Here we can see that the variable has the original description, but the new type.

Exception
~~~~~~~~~

We cannot change a parameter for a variable or a family implicitly.

This is always true, unless you want to change the default value of a child of a custom type in a family.

.. seealso::

   See the tutorial with a real world sample :ref:`custom type <tutorial_custom_type>`.
