Skip to content

Instantly share code, notes, and snippets.

@shuax
Created July 2, 2014 06:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save shuax/2d70bbf299f553d8369d to your computer and use it in GitHub Desktop.
Save shuax/2d70bbf299f553d8369d to your computer and use it in GitHub Desktop.
lua decorator,类似python那样的装饰器
local function decorator(str)
local rebuild_str = {}
local rebuild_fun = "(\0)"
local state = 0
for line in str:gmatch('[^\r\n]+') do
if line:find("@") then
rebuild_fun = string.format("(%s"..rebuild_fun..")", line:sub(2))
state = 1
else
if state==0 or state==3 then
table.insert(rebuild_str, line)
table.insert(rebuild_str, "\n")
elseif state==1 then
if line:find("function") then
local func = line:match("function%s(.*)")
local name, args = func:match("(%S+)%((.*)%)")
local newname = name .."__________decorator"
rebuild_fun = rebuild_fun:gsub("\0", newname..", "..args)
rebuild_fun = line.."\n\treturn " .. rebuild_fun .. "\nend"
table.insert(rebuild_str, (line:gsub(name, newname)))
table.insert(rebuild_str, "\n")
state = 2
else
assert(false, "after decorator need function")
end
elseif state==2 then
table.insert(rebuild_str, line)
table.insert(rebuild_str, "\n")
if line:find("end") then
state = 3
end
end
end
end
assert(state==3, "decorator error")
table.insert(rebuild_str, rebuild_fun)
local chunk = table.concat(rebuild_str)
local f, err = load(chunk)
assert(f, err)
f()
end
decorator[[
local function check_in(...)
local types = {...}
return function(f, ...)
local args = {...}
assert(#types==#args, "check_in args error")
for i,v in ipairs(args) do
assert(type(v)==types[i], "check_in args error")
end
return f, ...
end
end
local function check_out(...)
local types = {...}
return function(f, ...)
local function get_ret(...)
return {...}
end
local args = get_ret(f(...))
assert(#types==#args, "check_out args error")
for i,v in ipairs(args) do
assert(type(v)==types[i], "check_out args error")
end
return table.unpack(args)
end
end
@check_in("number", "number")
@check_out("boolean")
function test(a, b)
return true
end
]]
print( test(1, 2) )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment