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.