Modules et paquets Lua
Un module est similaire à une bibliothèque encapsulée. Depuis Lua 5.1, Lua a ajouté un mécanisme standard de gestion des modules, qui permet de placer du code commun dans un fichier et de l'appeler ailleurs sous la forme d'une interface API, ce qui favorise la réutilisation du code et réduit le couplage du code.
Un module Lua est une table composée d'éléments connus tels que des variables et des fonctions. Par conséquent, créer un module est très simple : créez une table, placez-y les constantes et les fonctions à exporter, et renvoyez enfin cette table. Ce qui suit est la création d'un module personnalisé module.lua. Le format du code du fichier est le suivant :
-- Définir un module nommé module
module = {}
-- Définir une constante
module.constant = "Ceci est une constante"
-- Définir une fonction
function module.func1()
io.write("Ceci est une fonction publique !"\n")
end
local function func2()
print("Ceci est une fonction privée !")
end
function module.func3()
func2()
end
return module
D'après ce qui précède, la structure d'un module est la structure d'une table, vous pouvez donc manipuler et appeler les constantes ou fonctions du module comme vous manipulez et appelez des éléments dans une table.
La func2 ci-dessus est déclarée comme une variable locale du bloc de programme, ce qui signifie qu'il s'agit d'une fonction privée. Par conséquent, cette fonction privée du module n'est pas accessible de l'extérieur et doit être appelée via la fonction publique du module.
Fonction require
Lua fournit une fonction appelée require pour charger des modules. Pour charger un module, il vous suffit de l'appeler. Par exemple :
require("<模块名>")
Or
require "<模块名>"
Après avoir exécuté require, il renvoie une table composée de constantes ou de fonctions du module, et définit également une variable globale contenant cette table.
Fichier test_module.lua
-- Le module module est le module.lua mentionné ci-dessus
require("module")
print(module.constant)
module.func3()
Le résultat d'exécution du code ci-dessus est :
This is a constant This is a private function!
Ou définissez une variable d'alias pour le module chargé afin de faciliter l'appel :
Fichier test_module2.lua
-- Le module module est le module.lua mentionné ci-dessus
-- Variable d'alias m
local m = require("module")
print(m.constant)
m.func3()
Le résultat d'exécution du code ci-dessus est :
This is a constant This is a private function!
Mécanisme de chargement
Pour les modules personnalisés, le fichier du module ne peut pas être placé dans n'importe quel répertoire. La fonction require possède sa propre stratégie de chargement des chemins de fichiers. Elle essaiera de charger le module à partir d'un fichier Lua ou d'une bibliothèque de programmes C.
Le chemin utilisé par require pour rechercher les fichiers Lua est stocké dans la variable globale package.path. Lorsque Lua démarre, il initialise cette variable avec la valeur de la variable d'environnement LUA_PATH. Si cette variable d'environnement n'est pas trouvée, un chemin par défaut défini au moment de la compilation est utilisé pour l'initialisation.
Bien sûr, s'il n'y a pas de variable d'environnement LUA_PATH, vous pouvez également personnaliser les paramètres. Ouvrez le fichier .profile dans le répertoire personnel de l'utilisateur actuel (créez-le s'il n'existe pas, ou ouvrez le fichier .bashrc). Par exemple, ajoutez le chemin "~/lua/" à la variable d'environnement LUA_PATH :
#LUA_PATH export LUA_PATH="~/lua/?.lua;;"
Les chemins de fichiers sont séparés par des points-virgules ";". Les 2 derniers ";;" signifient que le chemin nouvellement ajouté est suivi du chemin par défaut d'origine.
Ensuite, mettez à jour les paramètres des variables d'environnement pour qu'ils prennent effet immédiatement.
source ~/.profile
À ce moment, supposons que la valeur de package.path est :
/Users/dengjoe/lua/?.lua;./?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua;/usr/local/lib/lua/5.1/?.lua;/usr/local/lib/lua/5.1/?/init.lua
Ensuite, lors de l'appel de require("module"), il essaiera d'ouvrir les répertoires de fichiers suivants pour rechercher la cible.
/Users/dengjoe/lua/module.lua; ./module.lua /usr/local/share/lua/5.1/module.lua /usr/local/share/lua/5.1/module/init.lua /usr/local/lib/lua/5.1/module.lua /usr/local/lib/lua/5.1/module/init.lua
Si le fichier cible est trouvé, package.loadfile sera appelé pour charger le module. Sinon, il recherchera la bibliothèque de programmes C.
Le chemin de recherche des fichiers est obtenu à partir de la variable globale package.cpath, et cette variable est initialisée via la variable d'environnement LUA_CPATH.
La stratégie de recherche est la même que ci-dessus, sauf qu'elle recherche maintenant des fichiers de type so ou dll. S'il est trouvé, require le chargera via package.loadlib.
Paquets C
Lua et C sont faciles à combiner, en utilisant C pour écrire des paquets pour Lua.
Contrairement à l'écriture de paquets en Lua, les paquets C doivent d'abord être chargés et connectés avant utilisation. Dans la plupart des systèmes, la méthode d'implémentation la plus simple passe par le mécanisme de bibliothèque de liaison dynamique.
Lua fournit toutes les fonctions de liaison dynamique dans une fonction appelée loadlib. Cette fonction a deux paramètres : le chemin absolu de la bibliothèque et la fonction d'initialisation. Ainsi, un exemple d'appel typique est le suivant :
local f = loadlib(path, "luaopen_socket")
La fonction loadlib charge la bibliothèque spécifiée et la connecte à Lua. Cependant, elle n'ouvre pas la bibliothèque (c'est-à-dire qu'elle n'appelle pas la fonction d'initialisation). À la place, elle renvoie la fonction d'initialisation en tant que fonction Lua, de sorte que nous pouvons l'appeler directement en Lua.
Si une erreur se produit lors du chargement de la bibliothèque dynamique ou de la recherche de la fonction d'initialisation, loadlib renverra nil et un message d'erreur. Nous pouvons modifier le code précédent pour détecter l'erreur, puis appeler la fonction d'initialisation :
-- Ou path = "C:\\windows\\luasocket.dll", ceci est sur la plateforme Windows
local f = assert(loadlib(path, "luaopen_socket"))
f() -- Ouvrir réellement la bibliothèque
En général, nous nous attendons à ce que la bibliothèque binaire publiée contienne un fichier stub similaire au segment de code précédent. Lors de l'installation de la bibliothèque binaire, elle peut être placée dans n'importe quel répertoire, et seul le chemin réel de la bibliothèque binaire correspondant au fichier stub doit être modifié.
Ajoutez le répertoire où se trouve le fichier stub à LUA_PATH. Après ce paramétrage, vous pouvez utiliser la fonction require pour charger la bibliothèque C.
Autres extensions