The best way in Elixir I could see is a mix of your original approach, and behaviours.
- Behaviour:
defmodule ExAws.Iam.Consumer do
@callback consume_response(String.t, String.t) :: any # (xml, action)
end
- Implementers:
defmodule User do
@behaviour ExAws.Iam.Consumer
def consume_response(xml, action), do: #...
end
- Refactor
dispatchto use router functions like so:
defp consumer(action) when action in @user_actions, do: User
defp consumer(action) when action in @access_key_actions, do: AccessKey
#...
defp dispatch(xml, action), do: consumer(action).consume_response(xml, action)
Code is not tested. But IMO this brings you close enough to some practical polymorphism while remaining terse enough.
(Another alternative would be to have a big module where you match on all possible combos but I don’t think it would be an improvement over your current approach – except maybe for having less source files.)






















