2012-11-21 60 views
0

如何在Lua中使表只讀? (特別是,與Lua 5.1的C#的Lua界面,但我不認爲這會改變任何東西) 我知道如何使用__index__newindex,但這並不妨礙有人運行: math = nil,這可能會導致進一步的腳本錯誤地執行。Lua讓表只讀

我現在的 「保護」 功能:

function protect(table) 
return setmetatable({}, { __index = table, 
__newindex = function(table, key, value) error("attempted to modify a read only table")   
end, __metatable = false }) end 

math = protect(math) 
math.sqrt = nil // successfully protected 
math = nil // this is bad and can happen! 
+1

你沒有提到你使用的是什麼Lua版本。這在這種情況下是相關的。 – Mud

+0

我已經更新了原來的職位 – user1840819

回答

5

全球環境只是一個表。在Lua 5.1中,每個函數(這是一個編譯的Lua腳本)都有自己的環境,您可以更改。如果你想要沙箱腳本,以便他們不能修改全局表,你可以通過替換他們的環境與沙箱。

基本上,您創建了一個只讀表,您可以將所需的內容放入您想要的內容中。您甚至可以設置您的metatable,以防止覆蓋現有元素,但允許他們修改當前不存在的條目(即:他們可以創建和使用他們自己的全局變量)。也就是說,除非您將用戶移除到rawget/rawset的能力,否則他們可以隨時退出沙箱並開始打破這些表格。

更安全的版本是通過複製功能爲每個腳本構建環境。而不是每個腳本獲得相同的表格,他們都會得到您在腳本無法觸及的地方鬆開的原始副本。

+0

我目前的沙箱代碼實際上是這樣的: http://pastebin.com/1kzCGztL(忽略標籤的使用;它沒有編譯) 我有一個「LuaManager」,這通過調用LuaManager.RunFile(「filename」)運行腳本 在這種情況下,我將如何隱藏全局變量? setfenv會工作嗎? – user1840819