2012-05-31 27 views
11

Trong Lua, có thể biết hàm nào đã gọi là hàm hiện tại.Lua - tìm ra chức năng gọi

Ví dụ

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


function b() 
    a() 
end 

là một cái gì đó như thể này?
Thư viện gỡ lỗi có chức năng như vậy không?

Trả lời

17

Bạn có thể sử dụng debug.traceback():

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


function b() 
    a() 
end 

b() 

đó sẽ in:

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

bạn có thể sử dụng debug.sethook() để thiết lập một cái móc đó được gọi là mỗi lần một số sự kiện đặc biệt xảy ra trong lua. nó có thể hữu ích cho những thứ như thế này.

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() 

'người gọi 1 in này được gọi từ người gọi2!'

debug.sethook có thể xử lý 3 ký tự khác nhau trong tham số thứ hai để bạn có thể cho biết khi nào cần thông báo cho bạn. 'c' có nghĩa là gọi hàm hook của bạn bất cứ khi nào hàm được gọi trong lua, 'r' có nghĩa là gọi hàm hook của bạn mỗi khi hàm trả về trong lua, và 'l' có nghĩa là gọi hàm hook của bạn bất cứ khi nào lua xử lý một dòng mã mới .

bạn có thể thiết lập để xây dựng dấu vết ngăn xếp tùy chỉnh của riêng bạn nếu bạn thực sự muốn, và bạn cũng có thể sử dụng debug.getlocal() trong móc để thậm chí cố gắng tìm ra đối số nào được truyền cho hàm được gọi của bạn.

chỉnh sửa cho lhf. đây thực sự là một cách đơn giản hơn nhiều để thực hiện những gì bạn đang yêu cầu, nếu bạn không cần theo dõi điều này và chỉ cần biết bối cảnh của hàm được gọi.

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

Bạn không cần phải gọi 'debug.getinfo' bên trong một móc. Bạn có thể gọi trực tiếp hàm 'debug.getinfo' bên trong hàm của mình. – lhf

+1

ha, bạn nói đúng. tôi đã thiết kế quá mức. tôi sẽ thêm một đoạn mã hiển thị một cách dễ dàng hơn. –

+1

Với tối ưu hóa cuộc gọi đuôi, phiên bản đơn giản hơn có thể cho kết quả không chính xác nếu lệnh gọi 'caller2' đến' caller1' kết thúc cuộc gọi đuôi được tối ưu hóa, vì nó ngăn không cho bổ sung vào ngăn xếp cuộc gọi. –

Các vấn đề liên quan