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.

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:

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

dotdotdotPaul
Okay, I'm having a heck of a time trying to figure out how to best handle the validation of belongs_to associations in Ecto. I'm sure I'...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
Kagamiiiii
Student & New to elixir. Nice language. I want to convert a english character, e.g. “a”, which is stored in a variable, to it’s asci...
New
nsuchy
Hi. I’ve noticed that Windows Powershell has it’s own IEX command and you cannot access Elixir’s IEX due to the conflict. This isn’t a cr...
New
mgjohns61585
Could someone help me? I'm making my first elixir program, number guessing game. I can't figure out how to convert the user's guess from ...
New
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
electic
Hi, I am new to Elixir. I am trying to use the DateTime component to insert a date into MySQL however the there seems to be no way to fo...
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
Codball
Mix format works fine if run from the cmd. I’ve followed this to facilitate the implementation into VSC which involves downloading an ext...
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

Other popular topics 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
KronicDeth
Elixir plugin for JetBrain’s IntelliJ Platform (including Rubymine) This is a plugin that adds support for Elixir to JetBrains IntelliJ...
289 35421 110
New
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
script
If I have a string “1000 cfu/ml” . I want to remove the characters and / and space . So the string is like this "1000" What is the ...
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
myronmarston
The Elixir Typespec docs show the following syntax for keyword lists in typespecs: # ... | [key: type] # keyword lis...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
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
ovidiubadita
Hey all, I discovered Elixir and I love it. I always wanted to learn a functional programming and I intended to go for Haskell, but afte...
New

We're in Beta

About us Mission Statement