web-dev-qa-db-fra.com

Charger les fichiers Lua par chemin relatif

Si j'ai une structure de fichiers comme celle-ci:

./main.lua
./mylib/mylib.lua
./mylib/mylib-utils.lua
./mylib/mylib-helpers.lua
./mylib/mylib-other-stuff.lua

Depuis main.lua, Le fichier mylib.lua Peut être chargé avec le chemin complet require('mylib.mylib'). Mais à l'intérieur de mylib.lua Je voudrais aussi charger d'autres modules nécessaires et je n'ai pas envie de toujours spécifier le chemin complet (par exemple mylib.mylib-utils). Si jamais je décide de déplacer le dossier, je vais avoir beaucoup de recherche et de remplacement. Existe-t-il un moyen d'utiliser uniquement la partie relative du chemin?

UPD. J'utilise Lua avec Corona SDK, si cela importe.

33
RocketR

Il existe un moyen de déduire le "chemin local" d'un fichier (plus concrètement, la chaîne qui a été utilisée pour charger le fichier).

Si vous avez besoin d'un fichier dans lib.foo.bar, vous pourriez faire quelque chose comme ceci:

require 'lib.foo.bar'

Ensuite, vous pouvez obtenir le chemin d'accès au fichier en tant que premier élément (et uniquement) ... variable, lorsque vous êtes en dehors de toutes les fonctions. En d'autres termes:

-- lib/foo/bar.lua
local pathOfThisFile = ... -- pathOfThisFile is now 'lib.foo.bar'

Maintenant, pour obtenir le "dossier", vous devez supprimer le nom de fichier. Le moyen le plus simple est d'utiliser match:

local folderOfThisFile = (...):match("(.-)[^%.]+$") -- returns 'lib.foo.'

Et voila. Vous pouvez maintenant ajouter cette chaîne à d'autres noms de fichier et l'utiliser pour demander:

require(folderOfThisFile .. 'baz')     -- require('lib.foo.baz')
require(folderOfThisFile .. 'bazinga') -- require('lib.foo.bazinga')

Si vous déménagez bar.lua around, folderOfThisFile sera automatiquement mis à jour.

34
kikito

Tu peux faire

package.path = './mylib/?.lua;' .. package.path

Ou

local oldreq = require
local require = function(s) return oldreq('mylib.' .. s) end

Alors

-- do all the requires
require('mylib-utils')
require('mylib-helpers')
require('mylib-other-stuff')

-- and optionally restore the old require, if you did it the second way
require = oldreq
15
Seth Carnegie

Sous l'environnement Lua de Conky, j'ai réussi à inclure mon common.lua (Dans le même répertoire) que require(".common"). Notez le caractère point . En tête.

0
Vladius

J'utilise l'extrait de code suivant. Il devrait fonctionner à la fois pour les fichiers chargés avec require et pour les fichiers appelés via la ligne de commande. Utilisez ensuite requireRel au lieu de require pour ceux que vous souhaitez charger avec un chemin relatif.

local requireRel
if arg and arg[0] then
    package.path = arg[0]:match("(.-)[^\\/]+$") .. "?.lua;" .. package.path
    requireRel = require
elseif ... then
    local d = (...):match("(.-)[^%.]+$")
    function requireRel(module) return require(d .. module) end
end
0
jcai