• Hack: Function overloading in Lua
    10 replies, posted
Short backstory: Start of second semester of Computer Science. I liked function overloading in Java, so I decided to write it in lua. [lua]--getparams by Deco. local function getparams(f) local co = coroutine.create(f) local params = {} debug.sethook(co, function() local i, k = 1, debug.getlocal(co, 2, 1) while k do if k ~= "(*temporary)" then table.insert(params, k) end i = i+1 k = debug.getlocal(co, 2, i) end error("~~end~~") end, "c") local res, err = coroutine.resume(co) if res then error("The function provided defies the laws of the universe.", 2) elseif string.sub(tostring(err), -7) ~= "~~end~~" then error("The function failed with the error: "..tostring(err), 2) end return params end local _C = {} function setMeta(v) setmetatable(v, { __index = function(t,k) return function(...) if _C[t] and _C[t][k] and _C[t][k][#{...}] then return _C[t][k][#{...}](...) end end end, __newindex = function(t,k,v) if type(v) == "function" and #getparams(v) then _C[t] = _C[t] or {} _C[t][k] = _C[t][k] or {} _C[t][k][#getparams(v)] = v return; end if type(v) == "table" then setMeta(v) end return rawset(t,k,v) end, }) end local scanned = {} local function scanTable(tbl) for k , v in pairs(tbl) do if type(v) == "table" and not scanned[v] then scanned[v] = true setmetatable(v, { __index = function(t,k) return function(...) if _C[t] and _C[t][k] and _C[t][k][#{...}] then return _C[t][k][#{...}](...) end end end, __newindex = function(t,k,v) if type(v) == "function" and #getparams(v) then _C[t] = _C[t] or {} _C[t][k] = _C[t][k] or {} _C[t][k][#getparams(v)] = v return; end if type(v) == "table" then setMeta(v) end return rawset(t,k,v) end, }) scanTable(v) end --[[if type(v) == "function" and getparams(v) then _C[tbl] = _C[tbl] or {} _C[tbl][k][#getparams(v)] = v tbl[k] = nil end]] end end scanTable(_G) [/lua] Usage: Overloading can only be done on the number of parameters in a function. This hack automatically overloads every global function created after it (I was going to overload previous funcs, but that got messy). Simply define your function as normal, multiple times with different numbers of parameters. If you create multiple functions with one number of parameters, it will get overwritten; though preventing that would be trivial. [lua]-- EXAMPLE CODE -- -- In normal lua, this would throw a nil error. print("-- TEST BEGINNING--") function a(b) print(b) end function a(b,c) print(b .. c) end function a(b,c,d) print(b .. c .. d) end function a(b,c,d,e) print(b .. c .. d .. e) end function a(b,c,d,e,f) print(b .. c .. d .. e .. f) end a("1") a("1", "2") a("1", "2", "3") a("1", "2", "3", "4") a("1", "2", "3", "4", "5") lib = {} function lib.pow() print("No args") end function lib.pow(a) print("One arg") end function lib.pow(a,r) print("POWER!") end lib.pow() lib.pow("ar") lib.pow("e" , "r")[/lua] Outputs: [code]-- TEST BEGINNING-- 1 12 123 1234 12345 No args One arg POWER![/code] Practical uses: None that I can think of. However, as both a POC and also incase anyone really loves Java and wants to use this; they'll likely feel at home. Enjoy. (Also, it should work in most versions of Lua) I know a lot of you (garry) think I'm an utter dick. But still, have fun -Flap
Wonderful job! King'd.
Looking at the way it works, I guess thats not working for local functions? [editline]27th January 2012[/editline] Looking at the way it works, I guess thats not working for local functions? Also, aren't coroutines broken?
[QUOTE=Wizard of Ass;34406159]Looking at the way it works, I guess thats not working for local functions?[/QUOTE] Unfortunately not. It's possible to hack into local tables, and functions but it is an awful lot of effort and not really worth it for a POC. As far as I know coroutines aren't broken except when you pass objects into them. I can't test this in GMod because of something garry did that I'm not going to post publicly.
imo it's pretty pointless since Lua doesn't use specific data types for arguments. Or just using ... if a different amount of arguments are needed at different times.
[QUOTE=Nexus435;34406240]imo it's pretty pointless since Lua doesn't use specific data types for arguments.[/QUOTE] Will be useful in the cases where you have a different number of arguments, though. [QUOTE=Nexus435;34406240]imo it's pretty pointless since Lua doesn't use specific data types for arguments. Or just using ... if a different amount of arguments are needed at different times.[/QUOTE] That still requires the (ugly) if-elses to sort it all out.
[QUOTE=Bawbag;34406260]Will be useful in the cases where you have a different number of arguments, though. That still requires the (ugly) if-elses to sort it all out.[/QUOTE] That is true, but there are not many cases in Lua where you need to overload functions. Good job though.
[QUOTE=Nexus435;34406341]That is true, but there are not many cases in Lua where you need to overload functions. Good job though.[/QUOTE] I would argue that the cases don't exist, because it wasn't a feature previously. Sure, you don't [I]have[/I] to use "++" for things, but I would sure as hell use it if it existed in lua.
[QUOTE=Bawbag;34406173]something garry did that I'm not going to post publicly.[/QUOTE] Now you've made me curious. Ah, nevermind I know.
-snip
This is art.
Sorry, you need to Log In to post a reply to this thread.