Reputation: 390
I'm trying to build some objects in Lua. I found http://lua-users.org/wiki/ObjectProperties, and http://lua-users.org/wiki/SimpleLuaClasses, which allowed me to build:
package.path = "../src/?.lua;" .. package.path
require("class")
Feeds = {}
Feeds.__index = Feeds
-- Make proxy object with property support.
-- Notes:
-- If key is found in <getters> (or <setters>), then
-- corresponding function is used, else lookup turns to the
-- <class> metatable (or first to <priv> if <is_expose_private> is true).
-- Given a proxy object <self>, <priv> can be obtained with
-- getmetatable(self).priv .
-- @param class - metatable acting as the object class.
-- @param priv - table containing private data for object.
-- @param getters - table of getter functions
-- with keys as property names. (default is nil)
-- @param setters - table of setter functions,
-- with keys as property names. (default is nil)
-- @param is_expose_private - Boolean whether to expose <priv> through proxy.
-- (default is nil/false)
-- @version 3 - 20060921 (D.Manura)
local function make_proxy(class, priv, getters, setters, is_expose_private)
setmetatable(priv, class) -- fallback priv lookups to class
local fallback = is_expose_private and priv or class
local index = getters and
function(self, key)
-- read from getter, else from fallback
local func = getters[key]
if func then return func(self) else return fallback[key] end
end
or fallback -- default to fast property reads through table
local newindex = setters and
function(self, key, value)
-- write to setter, else to proxy
local func = setters[key]
if func then func(self, value)
else rawset(self, key, value) end
end
or fallback -- default to fast property writes through table
local proxy_mt = { -- create metatable for proxy object
__newindex = newindex,
__index = index,
priv = priv
}
local self = setmetatable({}, proxy_mt) -- create proxy object
return self
end
function Feeds:new(...)
local names = {
"material",
"diameter",
"flutes",
"pass_depth",
"stepover",
"entry",
"aggressiveness",
"spindle_speed",
"feedrate",
"entry_rate",
"sec_per_in",
"delta_t",
"feed_better",
"hp",
"hp_percent",
"deflection",
"defl_percent",
"mrr",
"surface_speed",
"chipload"}
local rv = {}
local p
for i, v in ipairs(...) do
if i <= #names then
-- print("for ".. i .. "\t" .. names[i] .. ": "..v)
rv[names[i]] = v
end
end
return make_proxy(Feeds, rv, Feeds_getters, Feeds_setters)
end
local Feeds_attribute_setters = {
material = function(self, material)
local priv = getmetatable(self).priv
assert(type(material) == "string")
priv.material = material
end
}
local Feeds_getters = {
b = function(self, value)
local priv = getmetatable(self).priv
return priv.a
end
}
Unlike the simple examples on the above web pages (a single parameter, called a
that's set to 5.), I have an object that takes 20 positional parameters. (They're columns from a spreadsheet.) The names of these parameters are shown as the local names
.
The parameters seem to be set properly, with the value passed in associated with the corresponding name in the priv
variable.
The problem is in accessing the class fields. If name
is the variable containing the name of the desired parameter, I need to be able to get the associated value.
actual = Feeds:new(arg)
print("name= " .. actual.name)
This doesn't work because (I think) .name
is supposed to be accessing the field called name
. If name="material"
, I want to get the value for value of name
, which is material
and the parameter material
's value, "MDF"
.
How do I do that?
Upvotes: 1
Views: 1427
Reputation: 26774
You're looking for actual[name]
. actual.name
is a syntax sugar for actual["name"]
, so you can pass a variable (name
in your case) instead of a literal value.
Upvotes: 3