[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Mutual requires
- From: Geoff Leyland <geoff_leyland@...>
- Date: Fri, 21 Dec 2012 08:59:30 +1300
On 21/12/2012, at 8:44 AM, Thijs Schreijer <thijs@thijsschreijer.nl> wrote:
> Interesting, but not sure I get it... could you post your original sample
> code, in this setup?
Attached. Note where "add" is required in expression.lua, after expression:new, but before the use of add. It's not quite like this in the actual code, but this kind of problem does turn up.
There's still a few style "issues".
It has to be resistant to requiring either expression or add first, so both need to set package.loaded, even though in this case main only requires expression.
Should I, then, just set package.loaded in all modules, or only the ones at risk of require loops?
Setting package.loaded means that you don't have to return the module at the end of the module, but should you anyway? Habits die hard.
----- expression.lua
local expression = {}
package.loaded.expression = expression
expression.__index = expression
function expression:new(o)
return setmetatable(o or {}, self)
end
local add = require("add") -- <----- HERE!
function expression.__add(a, b)
return add:new{a, b} -- I could 'require("add")' it here?
end
function expression.eval(exp, vars)
local mt = getmetatable(exp)
local f = mt and mt.__eval
return (f and f(exp, vars)) or exp
end
------ ref.lua
local expression = require("expression")
local ref = expression:new()
ref.__index = ref
ref.__add = expression.__add
function ref:__eval(vars)
return vars[self[1]] or self
end
function ref:__tostring()
return self[1]
end
return ref
----- add.lua
local add = {}
package.loaded.add = add
local expression = require("expression")
add = expression:new(add)
add.__index = add
add.__add = expression.__add
function add:__eval(vars)
local a = expression.eval(self[1], vars)
local b = expression.eval(self[2], vars)
if a == self[1] and b == self[2] then return self end
return a + b
end
function add:__tostring()
return tostring(self[1]) .. " + " .. tostring(self[2])
end
----- main.lua
-- local add = require("add")
local expression = require("expression")
local ref = require("ref")
local R = setmetatable({}, { __index = function(t, k) return ref:new{k} end })
print(expression.eval(R.a + R.b, { b = 2 }))