[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
**Subject**: **Re: Nested table constructor with reference to other children**
**From**: steve donovan <steve.j.donovan@...>
**Date**: Mon, 31 Oct 2011 13:21:51 +0200

On Sun, Oct 30, 2011 at 7:36 PM, Mark Hamburg <mark@grubmah.com> wrote:
> If one is going to play those sort of games, I would think -- not enough coffee yet to write -- that one could define functions to let one do the following:
Slightly different notation, same idea:
t = this.Expand {
x = 1.0,
t = {
c = this.y
},
y = this.x;
z = this.t.c
}
That is, 'this' is a general reference to the table The basic trick
is to define reference objects which basically are a chain of field
references.
-- expand.lua
local xmt = {}
this = setmetatable({},xmt)
local function is_fieldref (v)
return getmetatable(v) == xmt
end
local expand_fieldref, Expand
function xmt.__index (self,key)
if self == this then
if key == 'Expand' then return Expand end
self = setmetatable({},xmt)
end
self[#self+1] = key
return self
end
function expand_fieldref (root,keys)
local v = root
for _,k in ipairs(keys) do
v = v[k]
end
if is_fieldref(v) then
v = expand_fieldref (root,v)
end
return v
end
function Expand (t,root)
root = root or t
for k,v in pairs(t) do
if type(v) == 'table' then
if is_fieldref(v) then
t[k] = expand_fieldref(root,v)
else
Expand(v,root)
end
end
end
return t
end
(I put 'Expand' into 'this' just to keep things tidy)
The next step would be having references like this.x + 1, which is
perfectly possible (builds up little expression trees which are
evaluated later) but somewhat tedious to code. There are also some
gotchas with relational operators and function applications.
steve d.