roflbobl
Adding guard to macro that just calls another function
I have a problem, where i have a macro the calls another function. I want to be able to add optional guards to my macro, and call the nested function with those guards. I have a solution, but i feel like it is verbose and there is something i dont know of. Its the use of case do that feels clunky, and the only difference is the when clause.
Example
defmacro assert_push(
event,
payload,
timeout \\ 100
) do
case payload do
{:when, _, [pattern, guard]} ->
quote do
assert_receive %Phoenix.Socket.Message{
event: unquote(event),
payload: unquote(pattern)
}
when unquote(guard),
unquote(timeout)
end
_ ->
quote do
assert_receive %Phoenix.Socket.Message{
event: unquote(event),
payload: unquote(payload)
},
unquote(timeout)
end
end
end
Most Liked
sodapopcan
Honestly this looks fine to me—it’s nice and explicit. It’s not just the when clause that’s different but payload: unquote(pattern) v payload: unquote(payload). What you have is nice and explicit and I think DRYing it up would probably be more confusing (and hence a great case of “when DRY is too DRY”).
Although I see Chris K. is replying and he a notorious committer of macro crimes, so I’m interested to see what he’ll suggest ![]()
sodapopcan
He did not disappoint, but also made me more confident in my resolve
TIL about :elixir_utils.extract_guards which is very cool. But for what it’s worth, in a tense debugging session (or even just coming across it randomly in while trying to understand a system) I would much rather see your code.
christhekeele
Last Post!
roflbobl
@christhekeele @sodapopcan this is actually from Phoenix, so it is library code. I wanted to add the functionality as stated in my post for testing.
Popular in Questions
Other popular 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
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #hex
- #security










