lua-users home
lua-l archive

Re: 'with' statement

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


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.

AltStyle によって変換されたページ (->オリジナル) /