lua-users home
lua-l archive

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


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 }))