Skip to content

Instantly share code, notes, and snippets.

@marcoonroad
Forked from SegFaultAX/gist:3364849
Last active August 29, 2015 14:08
Show Gist options
  • Save marcoonroad/b603dacfcc0c48b9e033 to your computer and use it in GitHub Desktop.
Save marcoonroad/b603dacfcc0c48b9e033 to your computer and use it in GitHub Desktop.
function defmulti(keyfn)
if not keyfn then
keyfn = function(...) return ... end
end
local multi = {
_keyfn = keyfn,
_methods = {}
}
setmetatable(multi, {
__call = function(self, ...)
local key = self._keyfn(...)
if self._methods[key] then
return self._methods[key](...)
else
if self._methods.default then
return self._methods.default(...)
else
error("no dispatch for key: " .. tostring(key))
end
end
end
})
return multi
end
function defmethod(multi, key, fn)
if not multi._methods then
multi._methods = {}
end
multi._methods[key] = fn
end
fib = defmulti(tonumber)
defmethod(fib, 0, function() return 0 end)
defmethod(fib, 1, function() return 1 end)
defmethod(fib, "default", function(n) return fib(n-1) + fib(n-2) end)
print(fib(10))
greet = defmulti(function(user) return user.name end)
defmethod(greet, "mk", function() return "MK is 1337" end)
defmethod(greet, "mark", function() return "Mark is a lamer" end)
defmethod(greet, "default", function(user) return string.format("%s seems like a nice fellow", user.name) end)
print(greet({name = "mk"}))
print(greet({name = "mark"}))
print(greet({name = "steven"}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment