Files
elixir-koans/lib/koans/15_processes.ex
2017-01-21 08:18:10 -06:00

140 lines
3.0 KiB
Elixir

defmodule Processes do
use Koans
@intro "Processes"
koan "You are a process" do
assert Process.alive?(self()) == ___
end
koan "You can ask a process to introduce itself" do
information = Process.info(self())
assert information[:status] == ___
end
koan "Processes are referenced by their process ID (pid)" do
assert is_pid(self()) == ___
end
koan "New processes are spawned functions" do
pid = spawn(fn -> nil end)
assert Process.alive?(pid) == ___
end
koan "Processes can send and receive messages" do
send self(), "hola!"
receive do
msg -> assert msg == ___
end
end
koan "Received messages are queued, first in first out" do
send self(), "hola!"
send self(), "como se llama?"
assert_receive ___
assert_receive ___
end
koan "A common pattern is to include the sender in the message, so that it can reply" do
greeter = fn ->
receive do
{:hello, sender} -> send sender, :how_are_you?
end
end
pid = spawn(greeter)
send pid, {:hello, self()}
assert_receive ___
end
def yelling_echo_loop do
receive do
{caller, value} ->
send caller, String.upcase(value)
yelling_echo_loop()
end
end
koan "Use tail recursion to receive multiple messages" do
pid = spawn_link(&yelling_echo_loop/0)
send pid, {self(), "o"}
assert_receive ___
send pid, {self(), "hai"}
assert_receive ___
end
def state(value) do
receive do
{caller, :get} ->
send caller, value
state(value)
{caller, :set, new_value} ->
state(new_value)
end
end
koan "Processes can be used to hold state" do
initial_state = "foo"
pid = spawn(fn ->
state(initial_state)
end)
send pid, {self(), :get}
assert_receive ___
send pid, {self(), :set, "bar"}
send pid, {self(), :get}
assert_receive ___
end
koan "Waiting for a message can get boring" do
parent = self()
spawn(fn -> receive do
after
5 -> send parent, {:waited_too_long, "I am impatient"}
end
end)
assert_receive ___
end
koan "Trapping will allow you to react to someone terminating the process" do
parent = self()
pid = spawn(fn ->
Process.flag(:trap_exit, true)
send parent, :ready
receive do
{:EXIT, _pid, reason} -> send parent, {:exited, reason}
end
end)
receive do
:ready -> true
end
Process.exit(pid, :random_reason)
assert_receive ___
end
koan "Parent processes can trap exits for children they are linked to" do
Process.flag(:trap_exit, true)
spawn_link(fn -> Process.exit(self(), :normal) end)
assert_receive {:EXIT, _pid, ___}
end
koan "If you monitor your children, you'll be automatically informed for their depature" do
spawn_monitor(fn -> Process.exit(self(), :normal) end)
assert_receive {:DOWN, _ref, :process, _pid, ___}
end
end