lua-users home
lua-l archive

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


Hi all,

This hack du jour is for when you need forward references to a set of functions.

E.g.

mod = Forward()

funs = {mod.copy, mod.print, mod.eval}

function mod.print()
	print 'printing!'
end

function mod._not_implemented (name)
	print(name..' is not implemented')
end

for _,f in ipairs(funs) do f() end

==>
copy is not implemented
printing!
eval is not implemented

This is useful if say you are mocking up a user interface and want to
fill in all the functions; it also makes it easy to automatically
check whether all references have been satisfied.

This is done by making the __index function of our table create
references; when these are called, they forward to the actual
function, if available, otherwise produce a result which can be
customized by defining _not_implemented.

function Forward ()
	return setmetatable({},forward_MT)
end

forward_MT = {
	__index = function(mod,name)
		local ref = forward_ref(mod,name)
		mod[name] = ref
		return ref
	end
}

function forward_ref (mod,name)
	return setmetatable({mod=mod,name=name},forward_ref_MT)
end


forward_ref_MT = {
	__call = function(ref,...)
		local fun = rawget(ref.mod,ref.name)
		if type(fun) == 'function' then -- forward the call to the implementation
			fun(...)
		elseif rawget(mod,'_not_implemented') then -- wants to handle a miss...
			mod._not_implemented(ref.name)
		else
			error("'"..ref.name .. "' is not implemented",2)
		end
	end
}


steve d.