lua-users home
lua-l archive

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


On Mon, Aug 23, 2010 at 11:24 AM, Cuero Bugot <cbugot@sierrawireless.com> wrote:
>> If you don't mind adding a pair of parenthesis (or quotes) to the end
>> of the expression, you can get something pretty nice with __call :
>
> It is a good idea to use __call as a final table access indeed ! In that way it is easy to catch the last access to the path, and then call an appropriate getter internally.
> Your implementation seems to generate a lot of intermediary object though), but that may be optimized, using week tables so that at least it gets collected when unnecessary.


If you don't mind using strings, you can try this version:


local function get( tbl, str )
    local cur = tbl
    for part in str:gmatch( '([^.]+)' ) do
        if type( cur ) ~= 'table' then
            error( 'Invalid configuration key ' .. str ..
                    ' while reading ' .. part .. '. Parent key is not a table' )
        end
        cur = cur[ part ]
        if cur == nil then
            break
        end
    end
    return cur
end

cfg = { foo = { bar = { baz = 42 } } }
print( get( cfg, 'foo.bar' ) )
print( get( cfg, 'foo.bar.baz' ) )
--print( get( cfg, 'foo.bar.baz.ouch' ) ) --> error, but could be nil
print( get( cfg, 'non.existant' ) )


Or even a shortcut:

setmetatable( cfg, { __call = get } )
print( cfg 'foo.bar.baz' ) --> 42

--rb