lua-users home
lua-l archive

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



Oh, excellent.  Thanks for posting this :)

I'm of the opinion that all variables should be declared, period.  Not doing so leaves one open to typo errors that aren't discovered until obscure conditions happen at runtime, unless one has 100% test coverage of their code, which is generally not possible to accomplish.

CM


From: Graham Wakefield <wakefield@mat.ucsb.edu>
To: Lua mailing list <lua-l@lists.lua.org>
Sent: Wednesday, March 28, 2012 3:38 PM
Subject: Re: callstack recursive environment



On Mar 28, 2012, at 11:46 AM, Steve Litt wrote:

> It sounds to me, from your words above, that all globals go in _G. Now
> watch this...
>
> Give _G a metatable that, when you're in diagnostic mode, errors out on
> every global not specifically declared in _G's metatable ...

> SteveT
>

I think what you are describing is what strict.lua does, more or less:



--
-- strict.lua
-- checks uses of undeclared global variables
-- All global variables must be 'declared' through a regular assignment
-- (even assigning nil will do) in a main chunk before being used
-- anywhere or assigned to inside a function.
--

local getinfo, error, rawset, rawget = debug.getinfo, error, rawset, rawget

local mt = getmetatable(_G)
if mt == nil then
  mt = {}
  setmetatable(_G, mt)
end

mt.__declared = {}

local function what ()
  local d = getinfo(3, "S")
  return d and d.what or "C"
end

mt.__newindex = function (t, n, v)
  if not mt.__declared[n] then
    local w = what()
    if w ~= "main" and w ~= "C" then
      error("assign to undeclared variable '"..n.."'", 2)
    end
    mt.__declared[n] = true
  end
  rawset(t, n, v)
end
 
mt.__index = function (t, n)
  if not mt.__declared[n] and what() ~= "C" then
    error("variable '"..n.."' is not declared", 2)
  end
  return rawget(t, n)
end