Les transformations peuvent s'appeler elles-même, que ce soit dans la construction d'un résultat ou par la terminaison !nom . Afin d'éviter des conflits dans l'utilisation des variables, une transformation peut avoir des variables locales.
Ces variables existent pour chaque instance d'une transformation, c'est-à-dire qu'un jeu de variables locales est créé pour une transformation à chaque fois que cette transformation est appelée.
La transformation suivante retourne les données qu'elle reçoit écrites à l' envers ( Inverse ("ABC") produit CBA) :
/Inverse { DEBUT, RESTE } :
DEBUT c, RESTE 1~c = Inverse ( RESTE ) DEBUT.
/c = $00:$FF
La transformation Inverse isole le premier caractère des données et produit comme résultat :
Inverse ("ABC") effectue donc :
DEBUT <- "A", RESTE <- "BC", puis produit :
Inverse ("BC") , "A"
qui effectue :
DEBUT <- "B", RESTE <- "C", puis produit :
Inverse ("C") , "B"
qui produit "C"
Les variables DEBUT et RESTE doivent donc exister autant de fois que la transformation s'appelle elle-même.
L'utilisation de variables locales permet de rendre une transformation complètement indépendante des autres transformations : celles-ci risquent donc moins d'avoir des interrelations difficiles à voir.
ATTENTION!*nom détruit la dernière copie des variables locales de la transformation en cours, puis crée un jeu de variables locales pour la transformation appelée.
On indique après le nom d'une transformation, entre accolades, la liste de toutes les variables locales utilisées par cette transformation.
/nom {variable, ..., variable} :
Ces variables seront recréées à chaque appel de la transformation et détruites lorsqu'elle se termine.
Des variables locales sont donc créées:
- au départ, pour la première transformation du fichier des directives
- lors de l'appel à une sous-transformation par un constructeur
nom (constructeur)
- lors du passage à une autre transformation par une terminaison
!nom
ou!*nom
Vous maîtrisez maintenant un grand nombre d'outils pour la construction des résultats : vous pouvez donc construire dynamiquement (en cours d'exécution) à peu près n'importe quelle suite de caractères désirée.
Il peut être très utile de pouvoir faire varier dynamiquement la définition d' un patron de fouille :
? constructeur
permet de repérer dans les données en entrée exactement ce que le constructeur produit. Ce constructeur peut comprendre des noms de variables, des appels à des sous-transformations, etc.
?? constructeur
permet de repérer dans les données en entrée ce que le constructeur produit, sans tenir compte des différences entre majuscules, minuscules et lettres accentuées.
Par exemple : ?? NOM permet de repérer dans les données en entrée le contenu de la variable NOM sans tenir compte des différences entre majuscules, minuscules et lettres accentuées. Ou encore, la règle :
CARACTERE " ":"~", 1~ ?CARACTERE = CARACTERE.
élimine tous les caractères redoublés dans un fichier.
Par ailleurs, il peut arriver que pour décider si une série de données doit être traitée, il soit nécessaire de vérifier ce qui la suit. Le symbole \/ permet de séparer les patrons de fouille qui, si la règle s'applique, extraient définitivement des données en entrée, de ceux qui ne représentent qu'une vérification sur les données qui suivent sans extraction de données.
C'est dans les patrons de fouille d'une règle avec passage à une autre transformation (terminée par !nom ou par !*nom ) que l'on retrouve le plus souvent le symbole \/ En effet, les données qui déclenchent un passage d'une transformation à une autre doivent souvent être traitées selon les règles de l'autre transformation. Il faut donc que ces données soit repérées dans la première transformation mais extraites et traitées seulement dans la seconde.
Par exemple, dans des directives ADAPT qui transforment un rapport, la règle :
\/ "Total" !Sommaire
passe à la transformation Sommaire dès que le mot Total est détecté dans le rapport: ce mot et ce qui suit sera traité par Sommaire et non par la transformation appelante.