stjefim

stjefim

Get function name, module and arity from function capture

Hello!

I want to “save function” (module, name, arity) to the database to be able to call it later, potentially after BEAM was restarted. My plan is to use Functions.capture(module, function_name, arity) to be able to call the function after “loading” from the database.

How can I obtain module, function name and arity from a function capture (e.g. &MyModule.my_function/0) to “save function”? I have found Functions.info(fun) function, however, the documentation has a note saying that it should be used for debug only. What are the reasons it is debug only? What are the alternatives?

Marked As Solved

jswanner

jswanner

The underlying Erlang function docs says it’s “mainly” for debugging:

This BIF is mainly intended for debugging, but it can sometimes be useful in library functions that need to verify, for example, the arity of a fun.

That said, the :telemetry library uses it to verify you supply an external function as a handler.

Also Liked

al2o3cr

al2o3cr

The specific thing you’re looking for is :erlang.fun_info:

iex(1)> f = &String.capitalize/1
&String.capitalize/1

iex(2)> :erlang.fun_info(f)
[module: String, name: :capitalize, arity: 1, env: [], type: :external]

Note that it gives a possibly-unexpected result if given a capture that uses &n forms:

iex(3)> f2 = &String.starts_with?(&1, "foo")
#Function<42.39164016/1 in :erl_eval.expr/6>
iex(4)> :erlang.fun_info(f2)
[
  pid: #PID<0.0.0>,
  module: :erl_eval,
  new_index: 42,
  new_uniq: <<74, 179, 14, 23, 76, 2, 152, 184, 122, 207, 206, 42, 63, 68, 21,
    64>>,
  index: 42,
  uniq: 39164016,
  name: :"-expr/6-fun-3-",
  arity: 1,
  env: [
    {3, %{}, {:value, &:elixir.eval_local_handler/2},
     {:value, &:elixir.eval_external_handler/3}, %{},
     [
       {:clause, 3, [{:var, 3, :_capture@1}], [],
        [
          {:call, 3,
           {:remote, 3, {:atom, 3, String}, {:atom, 3, :starts_with?}},
           [
             {:var, 3, :_capture@1},
             {:bin, 3,
              [{:bin_element, 3, {:string, 3, ~c"foo"}, :default, :default}]}
           ]}
        ]}
     ]}
  ],
  type: :local
]
bartblast

bartblast

Creator of Hologram

Hey @stjefim, are you aware of Kernel.apply/3?

derek-zhou

derek-zhou

I don’t think there is a general solution as function can be anonymous. Also, storing function in a db may not be the best idea. Code will change, db record last for a long time. Also, think of the security implication.

Where Next?

Popular in Questions Top

aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
beno
I will often find my self writing things similar to: case some_value do nil -&gt; something() "" -&gt; something() _ -&gt; somethi...
New
siddhant3030
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
lastday4you
I wanted to check elixir version in phoenix because i found that my elixir is 1.5 but when i use Enum.chunk_by it said the function is un...
New
skosch
To my knowledge, put_in, Map.update etc. all have the one limitation of not automatically creating intermediate keys when needed (for exa...
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
SoCreat
i’m a new one to elixir which editor can i use vs code? or atom? Thanks! :smiley:
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
JorisKok
I have a server on AWS, and was running a load test using artillery. When looking at the Phoenix dashboard I see the Ports going to 100% ...
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

9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 43487 311
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
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID&lt;0.412.0&gt; terminating ** (Postgrex.Error) FATAL...
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
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
stefanluptak
Hello everybody, usually, I use a 29" ultra-wide monitor for VSCode which can easily accomodate explorer (files panel) + file with code ...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
AstonJ
We’ve put together this wiki for Phoenix LiveView - please feel free to add any info you feel is worth including. What is Phoenix LiveV...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement