2021-12-12 13:15:15
「プログラミング Elixir」の 第16章の練習問題4,5の解答例
「プログラミング Elixir」の 第16章の練習問題4,5の解答例
練習問題 OTP-Server-4
def start_link(initial_stack) do
GenServer.start_link(__MODULE__, initial_stack, name: __MODULE__)
end
呼び出し例
iex(2)> Sequence.Server.start_link([100, 200, 300])
{:ok, #PID<0.162.0>}
練習問題 OTP-Server-5
terminate コールバック実装例
def terminate(_reason, state) do
IO.puts "terminate: #{inspect(state)}"
end
呼ばれる例
iex(6)> Sequence.Server.pop
terminate: []
04:05:12.177 [error] GenServer Sequence.Server terminating
** (MatchError) no match of right hand side value: []
(sequence 0.1.0) lib/sequence/server.ex:42: Sequence.Server.handle_call/3
(stdlib 3.16.1) gen_server.erl:721: :gen_server.try_handle_call/4
(stdlib 3.16.1) gen_server.erl:750: :gen_server.handle_msg/6
(stdlib 3.16.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Last message (from #PID<0.159.0>): :stack
State: [data: [{'State', "My current state is '[]', and I'm happy"}]]
Client #PID<0.159.0> is alive
(stdlib 3.16.1) gen.erl:233: :gen.do_call/4
(elixir 1.13.0-rc.1) lib/gen_server.ex:1027: GenServer.call/3
(stdlib 3.16.1) erl_eval.erl:685: :erl_eval.do_apply/6
(elixir 1.13.0-rc.1) src/elixir.erl:289: :elixir.recur_eval/3
(elixir 1.13.0-rc.1) src/elixir.erl:274: :elixir.eval_forms/3
(iex 1.13.0-rc.1) lib/iex/evaluator.ex:310: IEx.Evaluator.handle_eval/3
(iex 1.13.0-rc.1) lib/iex/evaluator.ex:285: IEx.Evaluator.do_eval/3
(iex 1.13.0-rc.1) lib/iex/evaluator.ex:274: IEx.Evaluator.eval/3
** (EXIT from #PID<0.159.0>) shell process exited with reason: an exception was raised:
** (MatchError) no match of right hand side value: []
(sequence 0.1.0) lib/sequence/server.ex:42: Sequence.Server.handle_call/3
(stdlib 3.16.1) gen_server.erl:721: :gen_server.try_handle_call/4
(stdlib 3.16.1) gen_server.erl:750: :gen_server.handle_msg/6
(stdlib 3.16.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
push 時にサーバを終了させる例
# 10以上の数値を push した場合は続ける
def push(push) when push >= 10 do
IO.puts "push value is 10 or more"
GenServer.cast __MODULE__, {:stack, push}
end
# 10未満の数値を push した場合に終了
def push(push) when push < 10 do
IO.puts "push value is less than 10"
IO.puts "exit"
System.halt(0)
end
# 数値以外を push した場合に終了
def push(push) when not is_number(push) do
IO.puts "push value is not a number"
IO.puts "exit"
System.halt(0)
end
呼ばれる例
10未満の数値を push した場合に終了
iex(2)> Sequence.Server.start_link([100, 200, 300])
{:ok, #PID<0.170.0>}
iex(3)> Sequence.Server.push(100)
push value is 10 or more
:ok
iex(4)> Sequence.Server.push(10)
push value is 10 or more
:ok
iex(5)> Sequence.Server.push(9)
push value is less than 10
/home/trial/sequence #
数値以外を push した場合に終了
iex(2)> Sequence.Server.start_link([100, 200, 300])
{:ok, #PID<0.162.0>}
iex(3)> Sequence.Server.push(10)
push value is 10 or more
:ok
iex(4)> Sequence.Server.push("example")
push value is not a number
exit
/home/trial/sequence #