Skip to content

Instantly share code, notes, and snippets.

@mzfr
Created June 18, 2022 12:06
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 mzfr/8226e6c3d7558430b3c076cd73e8fa0a to your computer and use it in GitHub Desktop.
Save mzfr/8226e6c3d7558430b3c076cd73e8fa0a to your computer and use it in GitHub Desktop.
Solutions to The Little Elixir & OTP guidebook exercises
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