В настоящее время я изучаю Эликсир и читаю "Функциональная веб-разработка с помощью Эликсира, OTP и Феникса", и это отличная книга. Работая над главой конечного автомата, я придумал следующий код:
defmodule IslandsEngine.Rules do
alias __MODULE__
defstruct state: :initialized
def new(), do: %Rules{}
def check(%Rules{state: :initialized} = rules, :add_player), do:
{:ok, %Rules{rules | state: :players_set}}
def check(_state, _action), do: :error
end
Приведенный выше код должен работать как полнофункциональный конечный автомат. Я вставлю выше несколько команд iex:
iex(1)> alias IslandsEngine.Rules
IslandsEngine.Rules
iex(2)> rules = Rules.new()
%IslandsEngine.Rules{state: :initialized}
iex(3)> {:ok, rules} = Rules.check(rules, :add_player)
{:ok, %IslandsEngine.Rules{state: :players_set}}
iex(4)> rules.state
:players_set
Как видите, структура состояния изменилась с :initialized
на :add_player
. Отлично.
Мой вопрос: действительно ли структура state:
неизменна? Я имею в виду, что метод check/1
возвращает копию структуры с оператором state: :players_set
, который следует правильному функциональному шаблону... но как он «перезаписывает» текущий статус, не изменяя его напрямую?
Большое спасибо!