[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: disabling global definitions within function blocks
- From: "Thatcher Ulrich" <tu@...>
- Date: Tue, 7 Jan 2003 11:06:00 -0500
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