LuaTeX: Meilleures pratiques de codage Lua

Nov 17 2020

Quelles sont certaines des meilleures pratiques de codage à suivre lors du fractionnement et du chargement de code lua à partir de plusieurs fichiers lua externes, et lors du traitement du code lua d'autres packages lualatex. Cette pensée me vient à l'esprit car j'ai maintenant un tas de fichiers lua que je peux charger et utiliser, mais ce n'est pas le code le plus proprement divisé. Quelques questions posées comme « Side note » ici sont répétées ci - dessous avec plus de clarté (et ajouts):

  1. Concernant la portée, et possible conflit de noms des "variables locales" dans les fichiers lua externes: Dans le fichier linebreak.lua de cette question , quelle est la portée des variables locales local n, head, last? Si je charge un autre fichier lua avec "require", et qui a des variables locales nommées de la même manière, cela poserait-il un problème? Est-ce que lua garde les variables locales locales aux fonctions du fichier à partir duquel il est chargé? (même si je viens de les charger dans l'espace de noms global)

  2. Quelle est la meilleure pratique pour empêcher les variables et les fonctions d'un fichier d'entrer en conflit / de remplacer / d'interférer avec celles d'un autre fichier?

  3. Est-ce que cela fait partie des directives de documentation des développeurs de packages lualatex pour documenter ce qu'ils ajoutent à l'espace de noms global? Dans le cas où un package lualatex écrit un nom dans l'espace de noms global et qu'il entre en conflit avec le nom de ma variable / fonction, quel est le meilleur endroit pour commencer le débogage?

  4. Quelle est la portée entre deux blocs directlua / latelua différents? Dans mon observation, les variables locales sont locales aux blocs directlua, et j'ai fini par utiliser un espace de noms global dans le passé pour "passer" des valeurs d'un bloc directlua à un autre. Existe-t-il un moyen plus propre qui évite d'utiliser un espace de noms global?

Réponses

3 JosephWright Nov 17 2020 at 11:18

Les variables Lua sont locales à la fonction ou à la portée dans laquelle elles sont définies. Des fichiers source distincts constituent des portées, donc chacun require()signifie que les variables sont locales à ce fichier. Ceci est également vrai pour les \directluaappels, mais à part les applications triviales, vous devez charger le code Lua en utilisant une seule \directlua{require("myfile")}ligne. Je pense que plus de détails sur ce que vous faites sont nécessaires pour commenter davantage la «transmission d'informations entre les \directluaappels».

En règle générale, la meilleure façon de gérer les globaux est de déclarer une seule table et de contenir tout le matériel global. Il existe plusieurs façons, mais par exemple:

foo = foo or { }
foo.my_func = function(...)
end

ou

foo = foo or { }
local function my_func(...)
end
foo.my_func = foo.my_func or my_func

Si vous le souhaitez, vous pouvez inclure un test de sécurité pour le tableau global

if foo then
  print("Oh no, someone has taken my table")
  os.exit(1)
end

Il n'y a pas de documentation / système formel pour gérer l'espace de noms global. Je vous suggère de suivre la même approche que celle utilisée pour les macros TeX: choisissez un nom raisonnable en fonction du nom de votre package.