Skip to content

Instantly share code, notes, and snippets.

@kopos
Created November 28, 2017 06:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kopos/f70f41143e2572c30ebac711b5d33c6a to your computer and use it in GitHub Desktop.
Save kopos/f70f41143e2572c30ebac711b5d33c6a to your computer and use it in GitHub Desktop.
Stack module using receive loop, GenServer and Agent
defmodule Stack0 do
@moduledoc "
Stack module using the receive loop
iex> {:ok, pid} = Stack0.start_link([:a, :b])
{:ok, #PID<0.107.0>}
iex> Process.register pid, :stack0
true
iex> send pid, {:push, :c}
{:push, :c}
iex> send :stack0, {:push, :d}
{:push, :d}
iex> send pid, {:pop, self()}
{:pop, #PID<0.85.0>}
iex> send :stack0, {:pop, self()}
{:pop, #PID<0.85.0>}
iex> flush
:d
:c
:ok
"
def start_link(data) do
Task.start_link(fn -> loop(data) end)
end
defp loop(data) do
receive do
{:push, value} ->
loop([value | data])
{:pop, caller} ->
[h | t] = data
send caller, h
loop(t)
end
end
end
defmodule Stack do
@moduledoc "
Stack module using GenServer
iex> {:ok, pid} = GenServer.start_link Stack, [:a, :b], name: :stack
{:ok, #PID<0.120.0>}
iex> GenServer.cast pid, {:push, :c}
:ok
iex> GenServer.cast :stack, {:push, :d}
:ok
iex> GenServer.call pid, :pop
:d
iex> GenServer.call :stack, :pop
:c
"
use GenServer
def handle_call(:pop, _from, [h | t]) do
{:reply, h, t}
end
def handle_cast({:push, item}, state) do
{:noreply, [item | state]}
end
end
defmodule Stack2 do
@moduledoc "
Stack module using Agent
iex> {:ok, pid} = Stack2.start_link [:a, :b]
{:ok, #PID<0.123.0>}
iex> Stack2.push pid, :c
:ok
iex> Stack2.pop pid
:c
iex> Stack2.pop :stack2
:a
iex> Stack2.pop pid
:b
"
use Agent
def start_link(data) do
Agent.start_link(fn -> data end, name: :stack2)
end
def push(pid, value) do
Agent.update(pid, fn data -> [value | data] end)
end
def pop(pid) do
Agent.get_and_update(pid, fn [h | t] -> {h, t} end)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment