Current section
Files
Jump to
Current section
Files
lib/mutable.ex
defmodule Mutable do
@moduledoc """
Temporary side-effect module
"""
@mutable_key :mutable_key
@mutable_undefined :mutable_undefined
def run(keyword, fun) do
for {key, value} <- keyword do
push(key, value)
end
try do
fun.()
after
for {key, _} <- keyword do
pop(key)
end
end
end
defp push(key, value) do
mkey = {@mutable_key, key}
values = Process.get(mkey, [])
Process.put(mkey, [value | values])
end
defp pop(key) do
mkey = {@mutable_key, key}
case Process.get(mkey, @mutable_undefined) do
@mutable_undefined -> raise KeyError, key: key, term: get()
[_] -> Process.delete(mkey)
[_ | values] -> Process.put(mkey, values)
end
end
def get() do
Process.get()
|> Enum.filter(fn {{@mutable_key, _key}, _values} -> true
_ -> false end)
|> Enum.map(fn {{@mutable_key, key}, [value | _]} -> {key, value} end)
end
def get(key) do
mkey = {@mutable_key, key}
case Process.get(mkey, @mutable_undefined) do
@mutable_undefined -> raise KeyError, key: key, term: get()
[value | _] -> value
end
end
def put(key, value) do
mkey = {@mutable_key, key}
case Process.get(mkey, @mutable_undefined) do
@mutable_undefined -> raise KeyError, key: key, term: get()
[old_value | values] ->
_ = Process.put(mkey, [value | values])
old_value
end
end
end