Skip to content

Instantly share code, notes, and snippets.

@alex-eg
Forked from SegFaultAX/gist:3364849
Created June 5, 2013 09:22
Show Gist options
  • Select an option

  • Save alex-eg/5712708 to your computer and use it in GitHub Desktop.

Select an option

Save alex-eg/5712708 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