I have the following code in my GenServer:
def init(%State{} = state), do: {:ok, state, 1_000}
def init(opts \\ []) do
state = struct(State, opts)
{:ok, state, 1_000}
end
This code, as some of you may guess will generate the following warning:
definitions with multiple clauses and default values require a header. Instead of:
def foo(:first_clause, b \\ :default) do ... end
def foo(:second_clause, b) do ... end
one should write:
def foo(a, b \\ :default)
def foo(:first_clause, b) do ... end
def foo(:second_clause, b) do ... end
def init/1 has multiple clauses and defines defaults in one or more clauses
The warning is pretty good, but I don’t see how I can apply it. Mainly because init
can be called in 3 completely different ways:
passing a state
with no arguments
passing an options keyword list
How can I fix this?
1 Like
idi527
January 22, 2019, 9:30am
2
Just following the suggestion in the warning, maybe:
def init(opts \\ [])
def init(%State{} = state), do: {:ok, state, 1_000}
def init(opts) do
state = struct(State, opts)
{:ok, state, 1_000}
end
This is confusing to me. By doing it that way, I am saying that state
is actually an opts
, right ?
The problem is that it’s elixir creating multiple function heads for you here:
def init(), do: init([])
def init(%State{} = state), do: …
def init(opts), do: …
So it doesn’t really care about your patter match at all. It just needs to know that the first parameter is optional and shall be passed []
if not present. You could do:
def init(state_or_opts \\ [])
def init(%State{} = state), do: {:ok, state, 1_000}
def init(opts) do
state = struct(State, opts)
{:ok, state, 1_000}
end
4 Likes
NobbZ
January 22, 2019, 10:54am
5
Looking at your code, for me it seems much more like opts
beeing a listified %State{}
…