lua-users home
lua-l archive

Re: disabling global definitions within function blocks

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Jan 06, 2003 at 10:25 -0000, xenarcher <nickl@volition-inc.com> wrote:
> Consider the following Lua code:
> 
> SomeVariable = 1
> 
> function ClearSomeVariable()
> SomeVariabl = 0 -- NOTE THE TYPO!
> end
> 
> If the user accidentally writes the above code, typo and all, I want 
> to be able to catch this as a bug. However, the default 
> implementation of Lua allows global variables to be defined anywhere. 
> As such, the above code is quite valid and simply creates a second 
> global variable, "SomeVariabl", alongside the original 
> global, "SomeVariable".
> 
> My question is: is there an easy way to modify the Lua source to only 
> allow global variable definitions at the top level? (i.e.: outside 
> all code blocks, like C/C++) How would one go about doing this? There 
> must be some way to determine in the parser how many levels deep you 
> are. Even a simple assert to disallow the above code would be fine 
> for my purposes.
Here's some quickie draconian code that might fit your needs.
Basically it makes an error if you try to assign to a global whose
current value is nil (i.e. undefined). It doesn't catch typos until
run-time, but then it works with stock Lua 4.0.
---- guard_globals.lua ---
function catch_assignment_to_undefined_global(varname, newvalue)
	assert(rawget(globals(), varname) == nil)
	error("assignment to undefined global \"" .. varname .. "\"; use global(\"var\", val) to define global variables")
end
-- special function to define a global var.
function global(varname, newvalue)
	rawset(globals(), varname, newvalue)
end
function expose_globals()
	settagmethod(tag(nil), "setglobal", nil)	-- restore default behavior
end
function guard_globals()
	settagmethod(tag(nil), "setglobal", catch_assignment_to_undefined_global)
end
-- example usage
SomeVariable = 1
function ClearSomeVariable()
	SomeVariabl = 0		-- here's the typo
end
-- now see if we catch the typo
guard_globals()
ClearSomeVariable()
-- once guard_globals() is up, you can use global() to define a single new global,
-- or expose_globals() to turn off the guard.
---- end ----
-- 
Thatcher Ulrich
http://tulrich.com

AltStyle によって変換されたページ (->オリジナル) /