[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Forward References - a Useful Pattern
- From: Majic <majic.one@...>
- Date: Wed, 17 Feb 2010 03:22:24 -0800
Very nice, good post :)
On Wed, Feb 17, 2010 at 1:31 AM, steve donovan
<steve.j.donovan@gmail.com> wrote:
> 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.
>