defmodule GVA do @moduledoc """ Global VAriable utilities. All commands are prefixed with the letter `g` to prevent any clash with future `Kernel` functions. To use it in your script be sure to run at least Elixir `1.12` then import functions like the following: Mix.install([:gva]) import GVA An ETS table is used underneath meaning you can use any funky tricks to manipulate it data, pattern match and so on. No variable table is created by default, you have to do it by yourself. ## Examples Mix.install([:gva]) import GVA gnew :var gput :var, :answer, 42 gget :var, :answer # 42 gget_and_update :var, :answer, fn x -> 1 + x end # 43 """ @doc """ Create a new table to hold your variables. A table can hold as much variables (and associated data) as your RAM allows you. """ defmacro gnew(name) do quote do :ets.new(unquote(name), [:set, :protected, :named_table]) end end @doc """ Put a value in a variable table. """ defmacro gput(table, key, value) do quote do :ets.insert(unquote(table), {unquote(key), unquote(value)}) end end @doc """ Get an variable's value from a table by it's key. """ defmacro gget(table, key) do quote do [{_key, value}] = :ets.lookup(unquote(table), unquote(key)) value end end @doc """ Get and update a variable from a table by a function. Operation is probably not atomic and won't save you from race condition. (are you sure to write a script if you have these requirements?) `function` must be a function with an arity of 1. """ defmacro gget_and_update(table, key, function) do quote do unquote(table) |> gget(unquote(key)) |> then(unquote(function)) |> then(&gput(unquote(table), unquote(key), &1)) end end end