riccardomanfrin
Quote, defmacro and modules
I’m trying to understand how macros and module definitions interact with each others and I’m having few cases which I don’t understand. The below example has some pseudo doctest to show my doubts.
What I need is to support case 5. Thanks for the support in advance
defmodule Foo do
@doctest """
Case 1 OK: Trivial (and useless) case.. (Foo.Case1)
iex> Foo.Case1.foo
"local stuff"
Case 2 OK: Injects the Case2 in WrapMod and uses its args
WARNING: comment Case4 for this to work (head scratching)
iex> WrapMod.Case2.foo
[foo: "bar"]
Case 3 FAILED!!!! Injects used args into the Foo.Case3.foo function
Error:
example.ex:24: undefined function args/0 (expected Foo.Case3 to define
such a function or for it to be imported, but none are available)
Desiderata:
iex> Foo.Case3.foo
[foo: "bar"]
Case 4 KINDA NOT OK: Super clunky combo of case 2 and 1
It works, but it HIDES!!!!! Case 2: Call to `WrapMod.Case2.foo` is not available
anymore
iex> WrapMod.Case4.foo
"local stuff"
iex> WrapMod.Case2.foo
UndefinedFunctionError
Case 5 FAILED: Hyper clunky combo of case 2 with case 3 <- which is not working :(
This is where I'd want to get to: I would like to be able to invoke
and use the evaluated Foo.Case3.foo from within the quoted Case5 quoted module code
"""
defmacro __using__(args) do
#Case 1
defmodule Case1 do
def foo() do
"local stuff"
end
end
#Case 2
quote do
defmodule Case2 do
def foo() do
unquote(args)
end
end
end
#Case 3
#defmodule Case3 do
# def foo() do
# quote do
# unquote(args)
# end
# end
#end
# Case 4: comment me to get back WrapMod.Case2.foo which is otherwise no more available!!!
quote do
defmodule Case4 do
def foo() do
Case1.foo()
end
end
end
#quote do
# defmodule Case5 do
# def foo() do
# Case3.foo()
# end
# end
#end
end
end
defmodule WrapMod do
use Foo, foo: "bar"
end
For the records, case 3 works if I change it like this:
#Case 3
defmodule Case3 do
def foo() do
quote do
var!(args)
end
end
end
but this is giving me
iex(1)> Foo.Case3.foo
{:var!, [context: Foo.Case3, import: Kernel], [{:args, [], Foo.Case3}]}
which is clearly not what I want
Most Liked
fuelen
As in regular functions, macro returns the last expression.
It is not necessary to wrap two quote expressions into a list. You can simply wrap both module definitions into 1 quote block:
quote do
defmodule Case2 do
def foo() do
unquote(args)
end
end
defmodule Case4 do
def foo() do
Case1.foo()
end
end
end
1
Popular in Questions
Hello, how can I check the Phoenix version ?
Thanks !
New
Hi guys, i’m new in the Elixir world, and i have to say, that i love it!
i’m having some problem to understand anonymous functions with ...
New
I believe there are people here who are dealing with CSV files import on the daily basis, and since Excel is a really popular tool there ...
New
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
I am VERY much an elixir newbie. I have taken one elixir course and one phoenix course on Udemy. During that course, I saw the instructor...
New
Credo is smart enough to check for (something like) this:
assert length(the_list) == 0
with this response:
Checking if an enum is empt...
New
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service.
Currently when I de...
New
Other popular topics
Hi there,
I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
Lets say I have map like this fetching from my database
%{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
I asked this very same question on twitter and got some interesting feedback, but I thought it would be a good question to ask here as we...
New
Hi,
I have to write a raw query for one of my project. But till now I have used ecto queries and don’t have much experience writing raw ...
New
What learn first? Rust or Elixir
Hi Elixir community!
I’m here because i want learn a new language. I’m a junior developer and mainly i ...
New
We have an ECS cluster with 4 services, where each task joins a single cluster, via discovery ECS discovery service.
Currently when I de...
New
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
- #api
- #forms
- #metaprogramming
- #security
- #hex









