Created
June 18, 2022 12:06
-
-
Save mzfr/8226e6c3d7558430b3c076cd73e8fa0a to your computer and use it in GitHub Desktop.
Solutions to The Little Elixir & OTP guidebook exercises
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Stooge.Worker do | |
@moduledoc """ | |
Exercises from The Little Elixir & OTP Guidebook, Section 4.4. | |
Write a `GenServer` taht can store any valid Elixir term, given a key. Here are a few operations to get you started: | |
- `Cache.write(:stooges, ["Larry", "Curly", "Moe"])` | |
- `Cache.read(:stooges)` | |
- `Cache.delete(:stooges)` | |
- `Cache.clear(:stooges)` | |
- `Cache.exist(:stooges)` | |
""" | |
use GenServer | |
@name STG | |
#CLIENT | |
def start_link(opts \\ []) do | |
GenServer.start_link(__MODULE__, :ok, opts ++ [name: STG]) | |
end | |
def write(key, value) do | |
GenServer.call(@name, %{write: %{key: key, value: value}}) | |
end | |
def delete(key) do | |
GenServer.call(@name, %{delete: key}) | |
end | |
def read do | |
GenServer.call(@name, :read) | |
end | |
def exist?(key) do | |
GenServer.call(@name, %{exist: key}) | |
end | |
def clear() do | |
GenServer.cast(@name, :clear) | |
end | |
def stop() do | |
GenServer.cast(@name, :stop) | |
end | |
# SERVER | |
def init(:ok) do | |
{:ok, %{}} | |
end | |
def handle_call(%{write: %{key: key, value: value}}, _from, state) do | |
new_state = write_it_down(state, %{key: key, value: value}) | |
{:reply, :ok, new_state} | |
end | |
def handle_call(%{delete: key}, _from, state) do | |
new_state = delete_key(state, key) | |
{:reply, :ok, new_state} | |
end | |
def handle_call(:read, _from, state) do | |
{:reply, state, state} | |
end | |
def handle_call(%{exist: key}, _from, state) do | |
{:reply, has_key?(state, key), state} | |
end | |
def handle_cast(:clear, _state) do | |
{:noreply, %{}} | |
end | |
def handle_cast(:stop, state) do | |
{:stop, :normal, state} | |
end | |
## HELPER | |
def write_it_down(state, %{key: key, value: value}) do | |
case has_key?(state, key) do | |
true -> Map.update!(state, key, value) | |
false -> Map.put(state, key, value) | |
end | |
end | |
def delete_key(state, %{delete: key}) do | |
case has_key?(state, key) do | |
true -> Map.delete(state, key) | |
false -> state | |
end | |
end | |
def has_key?(state, key) do | |
Map.has_key?(state, key) | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment