desmond
Multiple callbacks for same function, different arguments
My application has many serializers for turning structs into something suitable for clients. These serializers have many serialize/1 functions defined to handle the nil case, list case, and finally the struct itself:
defmodule MyApp.ItemSerializer do
def serialize(nil), do: nil
def serialize(items) when is_list(items) do
Enum.map(items, serialize/1)
end
def serialize(item) do
%{
# ...
}
end
end
I’d like to have a @behaviour MyApp.Serializer directive to guarantee that individual implementations follow the contract of implementing all the serialize/1 functions. The problem is, it looks like callbacks only respect one function implementation, and creating many callbacks with the same function name but different typespecs does not help.
Is this the expected --ahem-- behavior of callbacks?
Most Liked
NobbZ
Why don’t you make it a protocoll? Then you could implement the list-case once in a defimpl X, for: List, the nil in defimpl X, for: Atom, while having discrete defimpl X, for: Y for your different structs.
michalmuskala
Here’s an idea - use a protocol with two callbacks - serialize_v1 and serialize_v2. For implementations where those are close enough or even the same, it’s pretty easy to delegate to a common implementation.
tty
This is linked to how functions are differentiated in the BEAM. Functions are differentiated by the module they reside in, their name and arity (number of arguments the function accepts). As such serialize/1 is the same function and the various function clauses a contraction of an if-else.
If having these 3 cases are import the define the 3 different functions in the behaviour individually e.g. serialize_nil/1, serialize_lists/1, serialize_item/1. The behaviour can auto-generate a serialize/1 which calls the relevant callbacks.
If you have many different structs perhaps look into using Protocols.







