Skip to content

Instantly share code, notes, and snippets.

@jcmoyer
Created June 5, 2013 19:47
Show Gist options
  • Save jcmoyer/5716720 to your computer and use it in GitHub Desktop.
Save jcmoyer/5716720 to your computer and use it in GitHub Desktop.
pre/post method hooks in Lua for AOP
--
-- dog
--
local dog = {}
function dog.new()
return setmetatable({ name = 'dog' }, { __index = dog })
end
function dog:run()
print("* " .. self.name .. " is running *")
end
function dog:sit(time)
print("* " .. self.name .. " is sitting for " .. time .. " seconds *")
end
--
-- poodle
--
local poodle = setmetatable({}, { __index = dog })
function poodle.new()
return setmetatable({ name = 'poodle' }, { __index = poodle })
end
--
-- doberman
--
local doberman = setmetatable({}, { __index = dog })
function doberman.new()
return setmetatable({ name = 'doberman' }, { __index = doberman })
end
--
-- aspect
--
local aspect = { mt = {} }
aspect.mt.__index = aspect
-- syntactic sugar
function aspect.mt.__call(asp, t)
return asp:apply(t)
end
function aspect.new(t)
local instance = {}
for k,v in pairs(t) do
instance[k] = v
end
return setmetatable(instance, aspect.mt)
end
function aspect:apply(t)
for k,v in pairs(self) do
local tv = t[k]
if type(tv) == 'function' then
local asp = self[k]
local prf
local pof
if asp.pre then
prf = function(...)
return tv(asp.pre(...))
end
else
prf = tv
end
if asp.post then
pof = function(...)
return asp.post(prf(...))
end
else
pof = prf
end
t[k] = pof
end
end
return t
end
--
-- limping
--
local limping = aspect.new({
run = {
post = function()
print("YELP!")
end
},
sit = {
pre = function(...)
local instance = select(1, ...)
local time = select(2, ...)
return instance, time * 50
end
}
})
--
-- main
--
local a = poodle.new()
local b = limping( doberman.new() )
a:run()
a:sit(10)
b:run()
b:sit(10)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment