ostap

ostap

Is it common to use `use` and `__using__` for re-dispatching?

In Phoenix apps, the web module provides this “re-dispatch into methods” technique for use (see __using__):

defmodule ExampleWeb.Router do
  use ExampleWeb, :router
end

defmodule ExampleWeb.TodoController do
  use ExampleWeb, :controller
end

defmodule ExampleWeb.Layouts do
  use ExampleWeb, :html
end

defmodule ExampleWeb do
  @doc """
  When used, dispatch to the appropriate controller/live_view/etc.
  """
  defmacro __using__(which) when is_atom(which) do
    apply(__MODULE__, which, [])
  end

  def router do
    #
  end

  def controller do
    quote do
      # ...
    end
  end

  def html do
    quote do
      # ...
    end
  end
end

What was the goal/benefit behind doing it that way? I’m guessing it’s for cutting on boilerplate, as otherwise it would’ve been:

defmodule ExampleWeb.TodoController do
  use ExampleWeb.Controller
end

defmodule ExampleWeb.Layouts do
  use ExampleWeb.HTML
end

defmodule ExampleWeb.Router do
  # hmm, probably inlined because same module name
end

defmodule ExampleWeb.Controller do
  defmacro __using__ do
    # ...
  end
end


defmodule ExampleWeb.HTML do
  defmacro __using__ do
    # ...
  end
end

Do we see more examples of this technique being used in libraries and projects besides Phoenix?

I’m trying to grasp the philosophy behind every decision :sweat_smile:

Marked As Solved

Eiji

Eiji

I think it’s rather an edge case especially to make code “shorter” and have a single “helper” module for this. It’s most probably because this code is not a part of a hex package, but a simple and short not documented (private functions have no documentation) part of your codebase. They are short and contains just a few aliases/imports and stuff like that. I would say it would be divided in few modules only if the inside logic would be more complex than what we have right now.

The entire ExampleWeb module logic is just so simple that it can’t compare to the logic of a typical macro. Also I believe it’s easier to maintain such helper in a single file rather than working on multiple files. The current Phoenix version have already impressive structure and does not need a bunch of tiny files just to separate such a simple logic.

Where Next?

Popular in Questions Top

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
chrisalley
ExUnit now has describe blocks which is a welcome addition coming from RSpec. In the docs, it states that nested hierarchies of describe ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lists...
New
LegitStack
I’m trying to make a websocket server in Phoenix or raw Elixir. I heard about gun, I think I could use cowboy, but since I’m not that sma...
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
earth10
Hi, I’m just starting to build a side-project with Elixir and Phoenix and doing some basic test with Elixir alone. What strikes me is th...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
svb
Hi! Currently I want to submit a form by pressing the Enter key. However, since my input field is of type “textarea” this is just adds a...
New

Other popular topics Top

johnnyicon
Hi all, I’ve just started learning Elixir and Phoenix Framework, so please pardon my n00bness at this stage. I’m trying to use Postgres...
New
msaraiva
Surface is an experimental library built on top of Phoenix LiveView and its new LiveComponent API that aims to provide a more declarative...
564 43757 214
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
RisingFromAshes
I’ve read in another post that it may be possible with a router helper - but I couldn’t find an appropriate one, and tbh, I’m still just ...
New
dblack
I’ve got an issue with an app and I’ve no idea of how to troubleshoot it. I’m hoping someone here might have seen something similar. I p...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
openscript
Hello! Sorry for this astonishing simple question, but I’m really stuck. I try to set up the intellij-elixir plugin, but I don’t know ho...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

We're in Beta

About us Mission Statement