2012-05-31 29 views
11

En Lua, es posible saber qué función ha llamado a la función actual.Lua - averiguar la función de llamada

Por ejemplo

function a() 
    get_calling_function() --Should print function b 
end 


function b() 
    a() 
end 

es algo como esto posible?
¿La biblioteca de depuración tiene tal funcionalidad?

Respuesta

17

Usted podría utilizar debug.traceback():

function a() 
    print(debug.traceback()) 
end 


function b() 
    a() 
end 

b() 

la que imprimiría:

 
stack traceback: 
    ./test.lua:45: in function 'a' 
    ./test.lua:50: in function 'b' 
    ./test.lua:53: in main chunk 
    [C]: in ? 
9

puede utilizar debug.sethook() para preparar un gancho que es llamada cada vez que ciertos eventos especiales suceden en lua. puede ser útil para cosas como esta.

local debugInfo = { caller = nil, callee = nil } 
function hook() 
    local info = debug.getinfo(2) 
    if info == nil then 
     debugInfo.callee = nil 
     return 
    end 

    -- we only want to watch lua function calls (not C functions) 
    if info.what ~= "Lua" then 
     debugInfo.callee = "C function" 
     return 
    end 

    debugInfo.caller = debugInfo.callee 
    debugInfo.callee = info.name 
end 


debug.sethook(hook, "c") 

function caller1() 
    if debugInfo.caller ~= nil and debugInfo.callee ~= nil then 
     msg = debugInfo.callee.. " was called by ".. debugInfo.caller.. "!" 
     print(msg) 
    end 
end 

function caller2() 
    caller1() 
end 


caller2() 

se llamó a esta persona que imprime1 desde caller2! '

debug.sethook puede manejar 3 caracteres diferentes en el segundo parámetro para que pueda saber cuándo notificarle. 'c' significa llamar a su función de enlace cada vez que se llama a una función en lua, 'r' significa llamar a su función de enlace cada vez que una función retorna en lua, y 'l' significa llamar a su función de enlace siempre que lua procese una nueva línea de código .

puede configurar esto para construir su propio rastro de pila personalizado si realmente lo desea, y también puede usar debug.getlocal() dentro de su gancho para intentar averiguar qué argumentos pasaron a su función llamada.

editar para lhf. esta es en realidad una forma mucho más simple de hacer lo que está pidiendo, si no necesita hacer un seguimiento de esto y solo necesita conocer el contexto de cómo se llamó a la función.

function caller1() 
    local current_func = debug.getinfo(1) 
    local calling_func = debug.getinfo(2) 
    print(current_func.name.. " was called by ".. calling_func.name.. "!") 
end 

function caller2() 
    caller1() 
end 
+4

No necesita llamar a 'debug.getinfo' dentro de un gancho. Puede llamar a 'debug.getinfo' dentro de su función directamente. – lhf

+1

ha, tienes razón. lo sobrediseñé. Añadiré un fragmento que muestra la manera más fácil. –

+1

Con la optimización de la llamada de la cola, la versión más simple podría dar resultados incorrectos si la llamada de 'caller2' a 'caller1' termina la llamada final optimizada, ya que impide una adición a la pila de llamadas. –

Cuestiones relacionadas