lua-users home
lua-l archive

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


Standard Lua does not support tag methods for "next" events. With a
little thought, I have come up with two reasons for wanting them:

(a) Consider a table that contains passwd entries, indexed, for
convenience, both by name and id (e.g., table["alan"] and table[10681]
both refer to the same value). To avoid duplicates, we wish to ignore
user id entries when we call next on this table, and this can be
easily accomplished with a suitable next tag method. (A more complex
scenario similar to this originally provoked me to think about this.)

(b) Now that Lua has tag methods, it is easy to create pseudo-tables
that have gettable and settable tag methods which access external data
as needed rather than access real table values. Some obvious
candidates from UNIX are the environment, the password file, and the
group file; wouldn't you rather write env.HOME instead of
getenv("HOME")? However, as it is, next does not work on these
pseudo-tables.

Fortunately, it is possible to spoof "next" tag methods. I append some
code to implement a "next" tag method and expose the original next
function as rawnext.

(Simple exercise: implement a pseudo-table that provides access to
global variables corresponding to setglobal, getglobal, and nextvar,
i.e., global[name] corresponds to getglobal(name) or setglobal(name,
...) and next(global, name) corresponds to nextvar(name).)

Regards,

Alan Watson

	if _nextmethod then
		return
	end

	_nextmethod = {}
	
	rawnext = next
	function next(table, index)
		local method = _nextmethod[tag(table)] or rawnext
		return method(table, index)
	end
	
	_settagmethod = settagmethod
	_gettagmethod = gettagmethod

	function settagmethod(tag, event, method)
		if event == "next" then
			local oldmethod = _nextmethod[tag]
			_nextmethod[tag] = method
			return oldmethod
		else
			return _settagmethod(tag, event, method)
		end
	end

	function gettagmethod(tag, event)
		if event == "next" then
			return _nextmethod[tag]
		else
			return _gettagmethod(tag, event)
		end
	end