alichoopani

alichoopani

Call external module funcs inside generated functions in macro

hello everyone.
I am trying to learn metaprogramming and start with simple project. in this road I this weird situation.
I want to implement interface like action_fallback macro in Phoenix controller(inside UseSample module).


defmodule GuardModule do
  def test() do
    IO.inspect("TEST")
  end
end

defmodule Sample do

  defmacro guard(module_name) do
    quote do
      @guard unquote(module_name)
    end
  end

  defmacro __using__(_opts) do
    quote do
      import unquote(__MODULE__)
      Module.register_attribute(__MODULE__, :guard, accumulate: :false, persist: :false)

      @before_compile unquote(__MODULE__)
    end
  end

  defmacro __before_compile__(env) do
    custom_guard = Module.get_attribute(env.module, :guard)
    custom_guard.test()
    # quote do
    #   def test_inside_use_sample() do
    #     custom_guard.test()
    #   end
    # end
  end
end

defmodule UseSample do
  use Sample

  guard GuardModule
end

now I have some questions.

  1. in Sample.__before_compile__ macro i can call external module functions. but i can’t generate function that call this external function inside its body(commented section not compile). how can I do that?
  2. in this situation GuardModule compiles before others because it’s in the beginning of file. how can I force elixir compiler to compile this module before Sample module?
  3. and finally am i have right solving strategy for this problem or should do something else?

thanks a lot.

Most Liked

rvirding

rvirding

Creator of Erlang

There are no problems for you to load in your version of that module again. There is no way to stop anyone from loading in new versions of any module. However there are some properties of code handling you should be aware of:

  1. There can at most be 2 versions of a module at the same time, the current and the old. When a new version is loaded in the old version is automatically and irrevocably deleted, the current version becomes the “new” old and the the new one becomes the “new” current.

  2. The system doesn’t try and be smart and say that if you already have the version of the module loaded it won’t reloaded It does what you tell it to.

  3. The code handling also kills all the processes using the old version of a module when that is deleted.

  4. This leads to some fun things. If you reload a module twice you are guaranteed to kill all processes running it regardless of which version they are running.

  5. When you call a function in a module which version you call depends on how it is called. If you make a local call you always get the same version while if you make a fully qualified call, Module.function, you always get a the current version. There is no way to explicitly call functions in the old versions from the “outside”.

Sorry for a quick description of code handling in the BEAM/Erlang/Elixir.

Where Next?

Popular in Questions Top

_russellb
I want to try my hand at web scraping. What tools/libraries do I need to use. I’m hoping to turn this into something professional so don’...
New
vertexbuffer
Hello, can anybody help here..? I have a list of players and I what to delete an element, but every for loop the list is reverting to ori...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
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
Lily
In templates/appointment/index.html.eex: <%= for appointment <- @appointments do %> <tr> <td><%= appoi...
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
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
vonH
In asking this question I am more interested about the expressiveness of the language itself and less concerned about the availability of...
New

Other popular topics Top

marius95
Hello everyone, I try to use an Javascript Event Handler in my root.html.leex file. Therefore I created a function in the app.js file: ...
New
stefanchrobot
What’s the safe way to decode a JSON string into a struct? I want to avoid calling String.to_atom. Jason.decode can give me a map with st...
New
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New
joaquinalcerro
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
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
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement