lkuty
I have a module for which I want to create a function rule_ids/0 at compile time. The code collects the rule ids at compile time from the first argument of all clauses of the function condition/3 using the AST.
It does not work because the variable rule_ids_ defined at compile time is not accessible when defining the function with def rule_ids(), do: rule_ids_.
How could I proceed to get it working? Should I use a macro somewhere?
defmodule Rules do
# Collect the rule ids at compile time
{_ast, rule_ids_} = File.read!(__ENV__.file)
|> Code.string_to_quoted()
|> Macro.traverse([],
fn
{:def, _, [{:condition, _, [rule_id, {:v, _, nil}, {:site, _, nil}]} | _]} = x, acc -> {x, [rule_id | acc]}
other, acc -> {other, acc}
end,
fn other, acc -> {other, acc} end
)
# How could I use rule_ids_ here?
def rule_ids(), do: rule_ids_
def condition(rule_id, v, site)
def condition(1018, v, site) do
v[site][7018] < 50 && v[site][7019] < 50 && v[site][7020] < 50
end
def condition(1017, v, site) do
v[site][7027] > 42
end
# ...
end
Trending in Questions
Hello!
Suppose you are building workflow (order / task / payment) processing system with the following requirements:
Each workflow con...
New
I’m aware of 2 such projects, are there others?
git: GitHub - team-alembic/realworld: A fullstack Phoenix LiveView application with back...
New
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
Other Trending Topics
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #performance










Showing Posts 1 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
D4no0
These is what module attributes are for: Module — Elixir v1.20.2
I’ve never checked it, but this should work:
LostKobrakai
There are better ways to do this over reading “yourself” and parsing the AST.
You can use
@on_definitionon a module (sayA) to have it call a macro or function elsewhere (Say onB) whenever a function or macro is defined on the module. With a macro being provided you can then pull information from those definitions and store them in an arbitrary module attribute ofA.You can register another callback
@before_compileinA, which calls the callback macro (likely also inB) right before the module starts compiling, but after all it’s body has been evaluated. That module can then read your arbitrary module attribute for all the gathered information and turn it into AST returned from the macro. That AST is then added to the module – you can imagine it being injected right before theendline ofdefmodule.lkuty
It worked with:
lkuty
I’ve put
@on_definition {Hooks, :rule_ids}in moduleRulesbut in the other module calledHooksI cannot see how I can accumulate the ids and make use of them in therule_ids/6function.LostKobrakai
You can use
Module.put_attribute, though I thinkHooks.rule_idsneeds to be a macro for that to work. The module attribute needs to be one on the module being compiled though, not on theHooksmodule.lkuty
I managed to make it work using both your advices. In fact I thought you had given two different ways of doing things but it looks like we have to combine them.
LostKobrakai
Yeah, that’s what I was hinting at. You can remove the hardcoded
Rulesin theHooksmodule by replacing it withenv.module. Often all the boilerplate you have inRulesis also contained in a__using__macro ofHooks, so ause Hooksdoes everything you need withinRules.mudasobwa
While everything suggested above is absolutely correct, I’m to answer your original question.
One does not technically need module attributes, nor hooks here. The issue is scopes and we have unquote fragments for that.
rule_ids_is defines in the outer scope forrule_ids/0call, therefore one needs to unquote it there. THe code below would work (I also fixed the issue withcondition/3head mistakenly falling under a match during the parse stage.)