It seems odd that state must be passed around all the time. Can't State
module hold itself, so I could do something like
state = %State{size: size}
case state.is_full? do
...
Here state is always passed. I suppose this is how it is in FP?
defmodule Chatter.Room do
use GenServer
defmodule State do
defstruct size: 3, players: []
def is_full?(state) do
Enum.count(state.players) >= state.size
end
def add_player(state, player) do
case State.is_full?(state) do
true -> {:room_is_full, state}
_ -> {:ok, append_player(state, player)}
end
end
defp append_player(state, player) do
%{state | players: state.players ++ [player]}
end
end
def open(size) do
{:ok, pid} = GenServer.start_link(__MODULE__, %State{size: size})
pid
end
def join(room, user) do
GenServer.call(room, {:join, user})
end
def players(room) do
GenServer.call(room, :players)
end
def init(state) do
{:ok, state}
end
def handle_call(:players, _from, state) do
{:reply, state.players, state}
end
def handle_call({:join, player}, _from, state) do
case State.add_player(state, player) do
{:ok, state} -> {:reply, :ok, state}
{error, state} -> {:reply, error, state}
end
end
end