apoorv-2204

apoorv-2204

Determining which module invoked a function( At Runtime)?

I have a module utils,which is supposed to be used by MOdule A, B,C,D… and so on. The issue is utils modules have lot of constants, constants specific to module A,B,C,D … . When i call module utils functions from module A, I want those functions to use constants defined in module A. same for B,C,D,… .What to use Import, use,etc.

So I can call module utils functions, so those util module functions can load constants depending upon which module has made the call.Opposed to passing as variable to the utils module functions. (since there is lot of functions).

So how to determine which module has invoked a function in another module at runtime. So I can leverage that information.

First Post!

sodapopcan

sodapopcan

There is discussion about this here.

I can’t quite visualize what you’re trying to do without seeing code, but if you have code like this:

defmodule A do
  @module B
end

I would advice against that since it results in B being a compile time dependency of A. If you have a lot of stuff like this, compilation can start to get really slow if you aren’t careful about your dependency graph. Otherwise—carry on.

Most Liked

benstepp

benstepp

It’s possible to do something similar with macros, but fair warning the general rule for macros is not to use them.

defmodule Util do
  defmacro do_something() do
    quote do
      Util.do_something_with(@constant)
    end
  end

  def do_something_with(constant) do
    IO.puts("The constant is #{constant}")
  end
end

defmodule A do
  require Util
  @constant 1

  def test() do
    Util.do_something()
  end
end

defmodule B do
  require Util
  @constant 2

  def test() do
    Util.do_something()
  end
end

defmodule C do
  require Util
  @constant 3

  def test() do
    Util.do_something()
  end
end

A.test()
# The constant is 1

B.test()
# The constant is 2

C.test()
# The constant is 3

al2o3cr

al2o3cr

I’m not going to even speculate along this line, because you shouldn’t do this.

Let’s talk about the underlying requirement instead.

Can you be more specific about what you mean by “having constants”? Modules don’t really “contain” anything - for instance, there’s no function in Module to get [Foo.Bar, Foo.Baz, Foo.Wat] given just Foo.

A common pattern for this is two parts:

  • functions that accept the module as an additional argument beyond the “public” API
  • a use macro that creates functions that include this extra argument in a user-controlled namespace

An example of this is Ecto.Repo.insert:

https://github.com/elixir-ecto/ecto/blob/f6ddc64fbb19588375137f70eea40bfaabf93804/lib/ecto/repo.ex#L304-L313

The underlying function is Ecto.Repo.Schema.insert, which accepts the repo as a first argument. In a default configuration with nobody calling put_dynamic_repo, that argument will be the module that said use Ecto.Repo.

In your case, you’d have a module in Utils that defines the __using__ macro and then use it in each of A, B, C, D like:

defmodule A.Utils do
  use Utils, some_config: "specific to A"
end

# in other A code:
A.Utils.do_stuff("x", "y")
# which then calls
Utils.do_stuff(A, "x", "y")

Where Next?

Popular in Questions Top

New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
ashish173
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
gshaw
What is the idiomatic way of matching for not nil in Elixir? E.g., First way: defp halt_if_not_signed_in(conn, signed_in_account) when...
New
fireproofsocks
Forgive me if this is obvious, but how does one delete a database record WITHOUT selecting it first? Ecto.Repo — Ecto v3.14.0 has exampl...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New

Other popular topics Top

KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 36689 110
New
nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
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
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
Harrisonl
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

We're in Beta

About us Mission Statement