Reputation: 1369
I want to have a user provided config file like this
-- file cfg.lua, provided or modifiable by user
cfg = {} -- global table
cfg.string_value = 153 -- supposed to be a string, user mistake
return cfg
And use it from somewhere such as if there's something wrong with the config file, I can tell the user what and where exactly went wrong
-- file init.lua
local cfg = require("cfg")
if type(cfg.string_value) ~= "string" then
error("config value 'string_value' expected a string")
end
And I want the error message to tell the user in which file and line is that value such as
ERROR:init.lua:6: config value 'string_value' expected a string
LOOK INSIDE cfg.lua: line 5
Is it possible to retrieve the file and line number from where a variable was declared?
Upvotes: 0
Views: 101
Reputation: 28950
Lua is dynamically typed. Any variable may have any type. So the only way to make sure that the correct type is assigned is by actually checking it.
You could use a proxy table to check wether the expected type was assigned. That way every assignment will pass through a function that makes sure we have matching types.
You can either define a type for each property or just use the type of it's default value.
You can use the debug library to get more information about where the assignment happened 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
Upvotes: 2
Reputation: 2793
For a number that has to be a string use...
-- 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
Upvotes: 0