A tiny macro to clean LiveView code

If you wanted to be really evil, you could overload the @ operator if the caller environment contains socket :smiling_imp:

defmodule Evil do
  defmacro __using__(_) do
    quote do
      import Kernel, except: [@: 1]
      import Evil
    end
  end

  import Kernel, except: [@: 1]

  defmacro @name do
    var = Macro.var(:socket, nil)

    if assigns_call?(__CALLER__, name) do
      {name, _, _} = name
      quote(do: Map.fetch!(unquote(var).assigns, unquote(name)))
    else
      quote(do: Kernel.@(unquote(name)))
    end
  end

  defp assigns_call?(env, {name, _, nil}) when is_atom(name) do
    Macro.Env.has_var?(env, {:socket, nil})
  end

  defp assigns_call?(_, _), do: false
end

defmodule Hmm do
  use Evil

  @okay :foo

  def maybe(socket) do
    @okay
  end

  def wow do
    @okay
  end
end

dbg(Hmm.maybe(%{assigns: %{okay: :NEAT!}}))
dbg(Hmm.wow())

(don’t do this)

7 Likes