[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: 'with' statement
- From: "Soni L." <fakedme@...>
- Date: Wed, 9 Mar 2016 07:17:52 -0300
On 09/03/16 06:06 AM, Dirk Laurie wrote:
Pascal introduced the construction
with tbl do
...
end
Inside the do block, fields of 'tbl' shadow outer variables.
This is hard to mimic exactly in Lua. Here is my attempt.
--- for _ENV in with(tbl,context) do ... end
-- * mimics Pascal `with`, i.e. not a real loop, just a do-once
-- * falls back to `context` which defaults to `_ENV`
-- * can be nested, outer level fields only visible if explicit
-- * temporarily deactivates metatable of `tbl`
local
function with(tbl,context)
local t=tbl
if type(t)~='table' then error("'with' expects a table, got "..type(t),2) end
local m=getmetatable(t)
return function()
if t then
t=nil
return setmetatable(tbl,{__index=context or _ENV})
else
setmetatable(tbl,m)
end
end
end
Problem 1: Local variables defined outside the `for` stay visible.
Problem 2: I can't think of a neat way to retain the metatable of `tbl`.
Try this:
local function with(t, e)
return setmetatable({}, {__index=function(t,k) return t[k] or e[k] end})
end
do local _ENV = with(tbl, _ENV)
-- stuff here
end
Doesn't solve 1 but seems much nicer than the for hack. It's also
simpler. It also supports non-tabke tbl/_ENV and metamethods in tbl.
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.