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
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
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
Hey @stjefim, are you aware of Kernel.apply/3?
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.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









