Modglobal
Modglobal provides a simple key:value store that is unique per module. You should use this when you would otherwise need to spin up a GenServer to track some simple state.
Full documentation: https://hexdocs.pm/modglobal.
Installation
def deps do
[
{:modglobal, "~> 0.2.2"}
]
end
Usage
Typically, the easiest way to use modglobal is to use get_global with a default value.
If you use modglobal in this way, you don’t need to hook up your module to your Application’s children,
as no PID is needed. This way also allows you to return {:error, error}
on application startup if the appropriate conditions aren’t held
defmodule Greeter do
use Modglobal
def save_name(name) do
set_global(:name, name)
end
def greet() do
name = get_global(:name, "world")
IO.puts("Hello, #{name}!")
end
end
However, if you have state that you want to initialize right away, and don’t want to stick it inside another process, you can do something like this:
application.ex
children = [
worker(Greeter, [])
]
greeter.ex
defmodule Greeter do
use Modglobal
def start_link() do
set_global(:name, "world")
:ignore
end
def greet() do
name = get_global(:name)
IO.puts("Hello, #{name}!")
end
end
Testing
When run in the test environment, the GenServer implementation is automatically replaced with a Mox struct.
Mox can be configured via the Modglobal.Mock
helper module as follows:
defmodule GreeterTest
alias Modglobal.Mock
test "greet returns the name passed in" do
Mock.setup(Greeter, [
{:set, [key: :name, value: "Ada"], nil},
{:get, [key: :name, default: nil], "Ada"},
]
Greeter.save_name("Ada")
assert capture_io(&Greeter.greet/1) == "Hello, Ada!"
end
end
where the format is Mock.setup(MODULE_NAME, commands)
,
and each command is a tuple of {command_name, args, return value}
corresponding to the appropriate data passed into the Modglobal.Server.Impl
functions.
You can customize this by overriding the :modglobal, :impl
environment and implementing your own definition of Modglobal.Server
.
For example, to use the real Modglobal in your tests, add this line to your config.exs config :modglobal, impl: Modglobal.Server.Impl