lua-users home
lua-l archive

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


Steve Dekorte wrote:
> 
> It seems like we ought to be able to implement a safeguard against
> global misuse by doing something like:
> 
>    function setglobal(i, v) print("no such local variable: '"..i.."'") end

Use this to catch assignments to undefined globals (=nil) instead:

	settagmethod(tag(nil), "setglobal", function(n,v) error(...) end)

Unfortunately you can't catch _all_ assignments.

> and then explicitly calling:
> 
>     globals().globalvarname = value
> 
> when we want to set a global. This doesn't seem to work though.
> Also, using a settable tag on the globals table doesn't work:
> 
>     local gtag = newtag()
>     settagmethod( gtag, "settable", function(t, i, v) print("no such
> local: '"..i.."'") end)
>     settag(globals(), gtag)
> 
> Is there no way to override the setting of globals?

In Sol I removed the set/getglobal tag methods and apply the regular
table tag methods for the global table too [1]. So

	foo = 1

may invoke the settable or newindex method of the global table.
To get what you want you just set one of these methods to the
global table and assign to them by a dummy global var.

	-- Sol has no settagmethod, newtag or settag.
	-- I've translated it to Lua syntax. [2]

	-- A dummy "global" var to set globals.
	local dummy_gtag = newtag()
	global = {} -- contents never used
	settag(global, dummy_gtag)
	settagmethod(dummy_gtag, "settable", function(t,n,v) rawset(globals(), n, v) end)
	settagmethod(dummy_gtag, "gettable", function(t,n) return rawget(globals(), n) end)

	-- and now forbid assignment to globals
	local gtag = newtag()
	settag(globals(), gtag)
	settagmethod(gtag, "settable", function(t,n,v) error("no such local "..n) end)
	-- this is optional: catch "read" of undefined globals
	settagmethod(gtag, "index", function(t,n) error("no such variable "..n) end)	
	
	global.foo = 1		-- ok
	print(foo)		-- 1
	print(global.foo)	-- 1  (the same as the simple foo but slower)
	print(bar)		-- error "no such variable bar"
	print(global.bar)	-- nil
	foo = 2			-- error "no such local foo"

But beware: even C code that calls lua_set/getglobal would be effected!

IMHO this handling of the global table is much more useful than the current
set/getglobal tag methods.  But that has already been discussed more than
once...

Ciao, ET


[1] Instead I've added a "newindex" method that gets called when a table
element whose old value is nil is written to.  It's similar to "index" but
for write access.

[2] If you are curious how it is written in Sol:

	global = {}
	methods(global, {
		function settable(t,n,v) rawset(globals(), n, v) end
		function gettable(t,n) return rawget(globals(), n) end
	})

	methods(globals(), {
		function settable(t,n,v) error("no such local "..n) end
		function index(t,n) error("no such variable "..n) end
	})