[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Safe navigation operator
- From: Romulo <romuloab@...>
- Date: Mon, 23 Aug 2010 11:50:05 -0300
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