1. 程式人生 > >Lua筆記——4.環境Environment

Lua筆記——4.環境Environment

變量 details then end fun true 全局環境 需要 時也

environment簡介:

Lua將其所有的全局變量保存在一個常規的table中,這個table稱為“環境”,並且為了便於像操作常規table一樣,Lua將環境table自身保存在一個全局變量_G中。
在默認情況,Lua在全局環境_G中添加了標準庫比如math、函數比如pairs、ipairs等,可以使用以下代碼打印當前環境中所有全局變量的名稱:

for n in pairs(_G) do
    print(n)
end

全局變量聲明

在Lua中,全局變量不需要聲明就可以直接使用,非常方便,但是這樣隨便使用全局變量,當出現bug時,也很難去發現,同時也汙染了程序中的命名。因為Lua所有的全局變量都保存在一個普通的表中,我們可以使用metatables來改變其他代碼訪問全局變量的行為,代碼如下:

setmetatable(_G,{
    __index = function(_,n)
        error("attempt to read an undeclared variable "..n,2)
    end,
    __newindex = function(_,n)
        error("attempt to write to undeclared variable "..n,2)
    end
})

改變訪問全局變量的行為之後,可以使用rawset,來繞過metatable,直接設置table的值:

--file: env.lua
--[[
test ={}

for n in pairs(_G) do
    print(n)
end


setmetatable(_G,{
    __index = function(_,n)
        error("attempt to read an undeclared variable "..n,2)
    end,
    __newindex = function(_,n)
        error("attempt to write to undeclared variable "..n,2)
    end
})

data = {}
--]]
local declaredNames = {}
function declare (name, initval)
    rawset(_G, name, initval)
    declaredNames[name] = true
end
setmetatable(_G, {
    __newindex = function (t, n, v)
    if not declaredNames[n] then
       error("attempt to write to undeclared var. "..n, 2)
    else
       rawset(t, n, v)   -- do the actual set
    end
end,
    __index = function (_, n)
    if not declaredNames[n] then
       error("attempt to read undeclared var. "..n, 2)
    else
       return nil
    end
end,
})

declare("data",{"sylvan","yan"})
print(data[1])

非全局的環境

TODO

REF

http://book.luaer.cn/
http://blog.csdn.net/xenyinzen/article/details/3485633

Lua筆記——4.環境Environment