I would like to get from “where” a particular function is executed. Is this possible in elixir? For example:
defmodule Sender do
def to(pid) do
send(pid, build_message())
end
defp build_message() do
%{
module: __MODULE__, # Can this be obtained at runtime?
from: self(),
message: "Hola!"
}
end
end
In the future I would like to separate the build_message function into its own thing so it doesn’t need to know the __MODULE__s value (which I guess its defined at compile time).
Macros might be a solution here but have been avoiding them wonder if anyone has any pointers on this?
Thanks @hauleth appreciate your comments and you’re probably right with the XY problem but let me better explain my case (which admitelly is not much of a use case at this point).
The idea behind comes from wanting to better standardize messaging between different system “components”; concretely I’m trying to apply a standard to messages between my LiveView and LiveComponent modules.
I have this struct defined:
defmodule Action do
defstruct [
module: Unknown,
message: "",
data: %{}
]
# Along with some constructor helpers
# ...
end
When sending messages between LiveComponents to LiveViews since both share the same pid, I’m thinking it would be nice to differentiate between them via the component’s module name:
# Although I'm using the Liveview framework as an example
# this probably not that important, it could be viewed as
# any process or genserver trying to send and catch a message.
# From the live component
defmodule LiveComponent.SendEmail do
use Web, :live_component
# mount, render, process callbacks
# send being a a helper function
defp send() do
send(self(), %Action{
module: __MODULE__,
message: "send-to",
data: %{to: "email@email.com", body: "Hello!"}
}
end
end
# From the liveview or process that receives the event
defmodule Web.Demo.TreatmentDisplayLive do
use Web, :live_view
# mount, render, process callbacks
# receive the message from the livecomponent
@impl true
def handle_info(msg = %{module: LiveComponent.SendEmail}, socket) do
case msg.message do
"send-to" ->
# process info...
_other ->
# process diferently...
end
end
I understand even this example will seem nonsensical, what is the point? why not just send a tuple? What I think this achieves is:
A little bit of “extra metadata” for pattern matching purposes, it is on the programmer’s end to enforce a match of this module.
Programmers reading the code might find it easier to parse and know where a message is coming from (module-wise speaking).
I’m currently just experimenting (not a clear path), but would like to expand this idea and see where it goes.