2010-05-14 5 views

Répondre

30

Voici une implémentation d'une fonction locals(). Il retourne une table de la population locale du champ d'application appelant:

function locals() 
    local variables = {} 
    local idx = 1 
    while true do 
    local ln, lv = debug.getlocal(2, idx) 
    if ln ~= nil then 
     variables[ln] = lv 
    else 
     break 
    end 
    idx = 1 + idx 
    end 
    return variables 
end 

Notez que dans le lua REPL, chaque ligne est un morceau séparé avec la population locale séparés. En outre, les variables internes sont renvoyés (les noms commencent par « (» si vous voulez les supprimer).

> local a = 2; for x, v in pairs(locals()) do print(x, v) end 
a 2 
(*temporary) function: 0x10359b38 

Merci pour l'accepter Vous avez débloqué le dernier morceau du casse-tête ;-)

!

Les valeurs supérieures sont des variables locales provenant d'étendues externes, utilisées dans la fonction en cours.Ils ne sont ni _G ni dans locals()

function upvalues() 
    local variables = {} 
    local idx = 1 
    local func = debug.getinfo(2, "f").func 
    while true do 
    local ln, lv = debug.getupvalue(func, idx) 
    if ln ~= nil then 
     variables[ln] = lv 
    else 
     break 
    end 
    idx = 1 + idx 
    end 
    return variables 
end 

Exemple (notez que vous devez utiliser un pour qu'il apparaisse):

> local a= 2; function f() local b = a; for x,v in pairs(upvalues()) do print(x,v) end end; f() 
a 2 
+0

Fonctionne parfaitement! Merci beaucoup! –

+0

Pourquoi il stocke 'paires' dans' (* temporaire) '? –

+0

heureux, c'est une chose de mise en œuvre de Lua – u0b34a0f6ae

0

Vous pouvez utiliser getfenv pour obtenir un environnement local.

getfenv ([f]) Renvoie l'environnement en cours d'utilisation par la fonction. f peut être une fonction Lua ou un nombre que spécifie la fonction à cette pile niveau: Niveau 1 est la fonction appelant getfenv. Si la fonction donnée n'est pas une fonction Lua, ou si f vaut 0, getfenv renvoie l'environnement global. La valeur par défaut pour f est 1.

Edit: désolé, je me suis trompé.

Je viens de vérifier le code source Lua. debug.getlocal() est le seul moyen d'obtenir les variables locales.
Lua utilise une structure interne Proto et ne nous donne pas accès à cela.
(Proto détient des propriétés locales plus un parent Proto, en utilisant getfenv,
nous parcourons également des propriétés héritées de la fonction référence Proto. Itère, pas ce que nous voulions)

Les utilisateurs peuvent définir leur Proto s soit avec des environnements et les fonctions set/getfenv ou en utilisant des métadonnées.

+0

Votre solution n'a pas fonctionné. Ce qui suit n'imprime pas 'foobar': local foobar = 1; pour k, v dans les paires (getfenv()) faire imprimer (k, v) fin Ai-je raté quelque chose? –

+0

Je crois que 'getfenv' montrera seulement des globals avec la portée/l'environnement donnés. –

+0

@Judge, oui, mais nous pouvons remplacer l'env de la fonction avec un autre. Comme je l'ai découvert, quand nous parcourons un env, nous parcourons aussi la chaîne héritée des prototypes internes. Nous ne pouvons pas vraiment obtenir de déclarations locales à moins d'utiliser le 'debug.getlocal' intégré. –

6

Utilisez debug.getlocal.

+3

C'est trop court pour être utile à quelqu'un qui arrive sur le web avec la question que j'ai posée. Mais merci quand même! –

2

Voir debug.getlocal:

local foobar = 1 

local i = 0 
repeat 
    local k, v = debug.getlocal(1, i) 
    if k then 
     print(k, v) 
     i = i + 1 
    end 
until nil == k 

Sortie:

foobar 1 
i  2 
+0

Avez-vous exécuté le code que vous avez collé? Je l'utilise en utilisant Lua 5.1.4 sur Ubuntu et il n'imprime rien du tout. J'ai enregistré le code sur un fichier et exécuté dans la console avec 'lua test.lua'. Est-ce que je manque quelque chose? –

+0

Oui, je l'ai couru sur Ubuntu 10.04 avec la même version de Lua. –

+0

L'avez-vous placé dans un fichier tel quel ou l'avez-vous enveloppé dans un appel de fonction? –

2

Le problème avec la version de la boucle du juge Maygarden est tout simplement local i = 0 ci-dessus. Il ne fait rien car le premier indexé avec '0' retournera toujours zéro. Rappelez-vous que les index Lua commencent par '1', pas '0' comme C/C++. Vous pouvez utiliser '0' pour un index avec vos propres types de cours, mais les fonctions par défaut attendent la valeur par défaut de '1' comme premier index.

Il suffit de le modifier à local i = 1 et sa boucle fonctionnera correctement.

Questions connexes