nelsonic
This is a bit of a “strange” question but please bare with me; I expect it will be useful/insightful to others learning Elixir/Phoenix wanting to understand the __using__/1 macro.
Context
Inside every Phoenix (Elixir Web Framework) App, at the bottom of the /lib/{yourapp}_web.ex file
e.g: /lib/chat_web.ex
there is a __using__/1 macro defined as:
@doc """
When used, dispatch to the appropriate controller/view/etc.
"""
defmacro __using__(which) when is_atom(which) do
apply(__MODULE__, which, [])
end
Question: what is the __using__/1 macro used for?
If you can, share (or link to) a usage example which will help demonstrate it in a real world context.
Where does the apply function come from given that it’s not “imported” in the /lib/{yourapp}_web.ex file and what is the effect of the “apply” ?
We have tried googling and reading several docs, tutorials, blog posts etc. on Macros. e.g:
- https://elixir-lang.org/getting-started/meta/macros.html
- Metaprogramming · Elixir School
- https://hackernoon.com/understanding-elixir-macros-3464e141434c
- https://medium.com/@Mike_Andr/understanding-elixirs-macros-by-phoenix-example-e99827a60987
But still no closer to understanding the why/when/how we would use __using__/1 macro …
If we attempt to comment out or delete it from lib/chat_web.ex the app does not compile even though it is not invoked from with chat_web.ex … and excoveralls (test coverage reporting) reports that it’s not being executed.
I find this confusing / non-beginner-friendly and searching the Phoenix guide (docs) is not particularly insightful e.g:
https://github.com/phoenixframework/phoenix/blob/29536f3b86154ab64647643a3eeeb263e33834cd/guides/controllers.md
Further context:
In the Phoenix Chat Example/Tutorial: GitHub - dwyl/phoenix-chat-example: 💬 The Step-by-Step Beginners Tutorial for Building, Testing & Deploying a Chat app in Phoenix 1.7 [Latest] 🚀 · GitHub
We are tracking test coverage as a learning exercise …
There is only one line of code that is not being covered by Tests:
Codecov
How is it that the line is not being executed (“covered”) when we run the tests, but if we comment out the line the tests fail?
Is this macro “magic” in that it is being “used” without actually being called?
Any shoshin insight much appreciated!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #ai
- #elixirconf-us
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming












Showing Posts 1 to 2- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Eiji
@nelsonic: Here are some helpful resources:
https://elixir-lang.org/getting-started/alias-require-and-import.html#use
Kernel — Elixir v1.20.2
What's 'use' statement in Elixir?
peerreynders
I have a demo app “rlp” from this topic. Looking at
rlp_web.exI notice this:Shortly thereafter this:
One thing you should notice is that each of these functions wrap:
That should tell you that the
controller,view,router,channelfunctions generate code. This happens at compile-time, not run-time. So these functions are intended for compile-time use, not run-time use.applyis simplyKernel.apply/3. And againdefmacrotells you that you are dealing with a compile-time construct.So
would become at compile time
which is equivalent to
which refers to that function we’ve just come across. So in
page_controller.ex:The
use RlpWeb, :controllercausesRlpWeb.controller()to be run at compile time which results in the code wrapped inquote do ... endbeing dumped unceremoniously intoRlpWeb.PageControllerresulting inNotice how there is now another
usethere that needs exactly the same treatment during compile time.Understanding exactly what code becomes available when during compilation can be a bit confusing. For that How does Elixir compile/execute code? may help.