lua-users home
lua-l archive

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


On 4 October 2016 at 16:14, Mike Jones <mike@mikejones.in> wrote:
> (I'm only starting to learn lua, but I am getting the impression that
> "ugly hack" and "cool feature" are the same thing in lua? lol)

It's an understandable impression to have, but there are good criteria
where to draw the line. If you're concerned with modularity (mixing
your code with other people's by loading libraries) and long-term
maintainability (no surprises for a future maintainer, who may be your
future self), some things here stand out as "red flags", namely the
_ENV tricks, and writing to standard API globals and tables.

The recommended style is for modules to return a table containing
their functions, instead of creating globals. This way, your chaining
function would receive two module tables (the original module and the
new one), and return the table of combined functions.

-- original.lua
local original = {}
function original.doSomething()
   print("original!")
end
return original

-- mod1.lua
local mod1 = {}
function mod1.doSomething()
   print("mod1!")
end
return mod1

-- main.lua
local prepend = require("prepend")
local original = require("original")
local mod1 = require("mod1")
local chained = prepend.chain(original, mod1)
-- you could of course chain more with
-- chained = prepend.chain(chained, mod2)
-- and so on
chained.doSomething()

-- prepend.lua
local prepend = {}
function prepend.chain(original, additions)
   local out = {}
   for name, func in pairs(original) do
      out[name] = func
   end
   -- This assumes that all functions in additions
   -- exist in original.
   for name, func in pairs(additions) do
      out[name] = function (...)
         -- replicating your chaining protocol here
         -- note it allows only one return value
         local ret = func(...)
         -- how about true as a stop-mark instead?
         if ret ~= 0 then return ret end
         return original[name](...)
      end
   end
   return out
end
return prepend

-- Hope this helps!

-- Hisham