Created
July 2, 2014 06:07
-
-
Save shuax/2d70bbf299f553d8369d to your computer and use it in GitHub Desktop.
lua decorator,类似python那样的装饰器
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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