--[[ "global" Library $Id: global.lua 8 2006-04-08 16:16:33Z cesar $ description: 未宣言のグローバル変数のアクセスをエラーにする。 usage: global(string1, string2, ...) stringの名前のグローバル変数を宣言する。 初期値はnil。 すでに存在するグローバル変数の場合もnilで初期化される。 global[string] = value 初期値の代入を伴う宣言。 global.name = value global["name"] = value の別表記。 global[string] グローバル変数へのアクセスであることを明瞭にする。 (_G[string] と同じ) global.name global["name"] の別表記。 example: require"global" global"var1" -- 宣言のみ。値はnil global.var2 = "init" -- 宣言と初期化 -- global.var3 -- Lua文法上、このような宣言は実装不可能 local x = global.var2 -- 代わりにprefixとしての利用が可能 -- global(var4) -- 宣言の時点でvar4が未宣言のためにエラー。このミスに注意。 global(var2) -- "var2"ではなく"init"という変数を宣言する。 global("var5", "var6") -- まとめて宣言。初期値はそれぞれnil。 global"f1" function f1() end -- f1 = function() end と同じなので宣言が必要 function global.f2() end -- global.f2 = function() end となり、宣言と定義を同時に行える example2: -- デバッグのときだけglobalを使う場合 -- (オーバーヘッドはほとんどないと思いますが、気になる方はどうぞ) Debug = true if Debug then require"global" end if global then global("var", "func") -- global宣言をifブロックにまとめる end var = 0 function func() end notice: 標準関数など、require"global"の前に定義されたグローバル変数は 宣言なくアクセスが可能。ただし値がnilになるとアクセスが不可能になる。 exclusionの設定不足により、標準関数等でエラーを起こす可能性がある。 license: GPL (とりあえず。) --]] local exclusion = { LUA_PATH = true, } local declared = {} local ERROR_STACK_LEVEL = 2 local mt = getmetatable(_G) or {} setmetatable(_G, mt) local function is_defined(v) return exclusion[v] or declared[v] end local function define_var(v) declared[v] = true end function mt.__index(table, key) if not is_defined(key) then error(string.format([[attempt to read undeclared global-variable "%s"]], key), ERROR_STACK_LEVEL) end return rawget(table, key) end function mt.__newindex(table, key, value) if not is_defined(key) then error(string.format([[attempt to write undeclared global-variable "%s"]], key), ERROR_STACK_LEVEL) end rawset(table, key, value) end rawset(_G, "global", setmetatable({}, { __index = _G, __newindex = function(table, var, value) define_var(var) rawset(_G, var, value) end, __call = function(func, ...) for i,v in ipairs(arg) do func[v] = nil end end, }) )