lua-users home
lua-l archive

[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

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`
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
       return setmetatable(tbl,{__index=context or _ENV})

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})

do local _ENV = with(tbl, _ENV)
  -- stuff here

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.