lua-users home
lua-l archive

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


On Mon, 23 Aug 2010 15:45:25 +0300, Cuero Bugot <cbugot@sierrawireless.com> wrote:

> local emptytable = {}
> local function Opt (t) return t or emptytable end
>
>   if config.Opt(network).Opt(server).url then
>     dosomething(config.network.server.url)
>   End
That does not make any sense. I do not know what I was thinking. Sorry
for the noise...

Well at least it illustrate what I meant by 'context'. Opt() is "in the middle path/table traversal" while the last ".url" is "the final access". If metamethods __index / __newindex did provide this kind of information then it would be easy to implement safe navigation operator with metatables Would that be something completely unrealistic to provide more contextual information as parameters of the __index / __newindex metamethods ?

If you don't care about perfomance, ...

======8<============================

v = {}
mt = {
    __index = function (t, k)
        local key
        local ret = {}
        if t and rawget(t, "_key") then
            key = t._key
            ret._container = t._container
        else
            key = {}
            ret._container = t
        end
        key[#key + 1] = k
        ret._key = key
        setmetatable(ret, mt)
        return ret
    end,
    __newindex = function (t, k, v)
        local key
        if t and rawget(t, "_key") then key = t._key else key = {} end
        key[#key + 1] = k
        io.write("assign ", v, " to")
        local sep = ' '
        for n,i in ipairs(t._key) do
            io.write(sep, i)
            sep = '.'
        end
        io.write(" in ", tostring(t._container), "\n")
    end
}

setmetatable(v, mt)

v.a.b.x.y.n.m = 1

======>8============================

Basically, you create proxy object that builds expression tree it is passing through (in this case, navigation path), and use __newindex as a trigger for needed action.

To access value, you need to define all sorts of __eq, __tostring, etc methods that
vould return configuration value pointed to by the proxy.

Being able to handle chains of operations in a single metamethod would really simplify
such cases, e.g., to have

__newindex(container, value, key, ...)

But I do not see how it is possible to add this without making it imcompatible with
existing code.