2015-04-25 1 views
4

parent j'ai une configuration de fichier comme ceci:nécessitant un module luajit dans un sous-répertoire est Écrasement d'un module du même nom dans le répertoire

main.lua (requires 'mydir.b' and then 'b') 
b.lua 
mydir/ 
    b.so (LuaJIT C module) 

De principale, je le fais:

function print_loaded() 
    for k, v in pairs(package.loaded) do print(k, v) end 
end 

print_loaded() 
require 'mydir.b' 
print_loaded() 

-- This would now include 'mydir.b' instead of 'b': 
local b = require 'b' 

Les sorties des print s montrent que mon appel à require 'mydir.b' définit la valeur de retour comme la valeur de package.loaded['b'] ainsi que le package.loaded['mydir.b'] attendu. Je voulais avoir package.loaded['b'] laissé non réglé afin que je puisse plus tard require 'b' et ne pas se retrouver avec la valeur (à mon avis erronée) en cache de mydir.b.

Ma question est: Quelle est une bonne façon de faire face à cela?

Dans mon cas, je veux être en mesure de copier autour mydir comme subdir de l'un de mes projets luajit, et ne pas avoir à se soucier de mydir.whatever polluer l'espace de noms de module en détruisant tout plus tard require s de whatever au répertoire parent niveau.

En anticipant les gens qui disent, "renommez simplement vos modules!" Oui. Je peux le faire. Mais j'aimerais savoir s'il existe une meilleure solution qui me permet de ne pas avoir à m'inquiéter des collisions de noms.

+0

Est-ce que votre 'b.lua' utilise la fonction' module' par hasard? – siffiejoe

+1

Non, ce n'est pas le cas. Ce comportement semble être indépendant du contenu de 'b.lua'. – Tyler

+0

La bibliothèque 'b.so' définit-elle' packages.loaded' (en utilisant 'module') n'importe où? –

Répondre

1

Le problème était que j'appelais incorrectement luaL_register depuis le fichier source de mon b.so (b.c).

Voici le mauvais code qui a causé le problème:

static const struct luaL_reg b[] = { 
    /* set up a list of function pointers here */ 
}; 

int luaopen_mydir_b(lua_State *L) { 
    luaL_register(L, "b", b); // <-- PROBLEM HERE (see below) 
    return 1;     // 1 = # Lua-visible return values on the stack. 
} 

Le problème avec la ligne en surbrillance est qu'il mettra spécifiquement package.loaded['b'] avoir la valeur de retour de ce module quand il est chargé. Cela peut être résolu en remplaçant la ligne par ceci:

luaL_register(L, "mydir.b", b); 

qui établira package.loaded['mydir.b'] à la place, et donc laisser la place pour une utilisation ultérieure d'un module du même nom (sans le préfixe mydir).

Je ne me suis pas rendu compte de cela longtemps après avoir posé cette question, quand je me suis finalement rendu à la lecture officielle docs for luaL_register pour Lua 5.1, qui est la version LuaJIT est conforme.

+0

IIRC, luaopen_whatever() est appelé avec un seul argument * modname * de require(), donc il est probablement plus correct d'utiliser cela à la place du nom codé en dur. – user3125367

+0

http://www.lua.org/manual/5.1/manual.html#pdf-require – user3125367

+1

Ou utilisez 'lua_newtable (L); luaL_register (L, NULL, b); La définition de variables globales à partir de modules n'est pas la meilleure pratique [plus] (http://lua-users.org/lists/lua-l/2010-08/msg00443.html). Un global nommé 'mydir.b' ne serait d'aucune utilité, car il faudrait écrire' _G ["mydir.b"] 'pour l'utiliser. – siffiejoe