Lua - 查找声明全局变量的文件

时间:2021-06-25 07:31:42

标签: lua

我想要一个像这样的用户提供的配置文件

-- file cfg.lua, provided or modifiable by user

cfg = {} -- global table

cfg.string_value = 153 -- supposed to be a string, user mistake

return cfg

并从某个地方使用它,例如如果配置文件有问题,我可以告诉用户什么地方出了什么问题

-- file init.lua

local cfg = require("cfg")

if type(cfg.string_value) ~= "string" then
    error("config value 'string_value' expected a string")
end

并且我希望错误消息告诉用户该值位于哪个文件和行中,例如

ERROR:init.lua:6: config value 'string_value' expected a string
      LOOK INSIDE cfg.lua: line 5

是否可以从声明变量的位置检索文件和行号?

2 个答案:

答案 0 :(得分:1)

Lua 是动态类型的。任何变量都可以有任何类型。因此,确保分配正确类型的唯一方法是实际检查它。

您可以使用代理表来检查是否分配了预期的类型。这样每个赋值都会通过一个函数来确保我们有匹配的类型。

您可以为每个属性定义一个类型,也可以仅使用其默认值的类型。

您可以使用调试库获取有关分配发生位置的更多信息https://www.lua.org/manual/5.4/manual.html#6.10

-- simulate loading a module
function require()
  local cfg = {
    string_value = {type = "string", value = "default"},
    table_value = {type = "table", value = {}},
  }
  local mt = {
    __index = function (t,k) return cfg[k].value end,
    __newindex = function (t,k,v)
      assert(type(v) == cfg[k].type, string.format(
        "attempted to assign a %s to config field %s. %s expected!",
        type(k), k, cfg[k].type))
      print(debug.traceback())
      cfg[k].value = v
    end
  }
  local interface = setmetatable({}, mt)

  return interface
end


local cfg = require("cfg")
cfg.string_value = "test"
print(cfg.string_value)
cfg.table_value = 4

答案 1 :(得分:0)

对于必须是字符串的数字,请使用...

-- file cfg.lua, provided or modifiable by user

cfg = {} -- global table

cfg.string_value = tostring(153) -- supposed to be a string
-- or: cfg.string_value = "153"

return cfg