Qqwy
So while writing Confy, I wanted to turn shorthand atoms like:integer, :string, :atom into the ‘normal’ forms &Confy.Parsers.integer/1, &Confy.Parsers.string/1, &Confy.Parsers.atom/1, etc.
However, I struggled to properly perform quoting and unquoting while using the function capture operator&.
In the end, I settled on the following snippet:
# Replaces simplified atom parsers with
# an actual reference to the parser function in `Confy.Parsers`.
# NOTE: I dislke the necessity of `Code.eval_quoted` here, but do not currently know of another way.
defp normalize_parser(parser) when is_atom(parser) do
case Confy.Parsers.__info__(:functions)[parser] do
nil -> raise ArgumentError, "Parser shorthand `#{inspect(parser)}` was not recognized. Only atoms representing names of functions that live in `Confy.Parsers` are."
1 ->
{binding, []} = Code.eval_quoted(quote do &Confy.Parsers.unquote(parser)/1 end)
binding
end
end
defp normalize_parser(other), do: other
Note the Code.eval_quoted line: Although it is probably safe since it is only executed when parser indeed is an atom and exists as a function inside the Confy.Parsers module, it does not feel nice to need it.
Is there another way to build a function capture out of a module and function atom?
Note that 'function captures like wrapping everything with fn are not what I am looking for, since the result of normalize_parser is also used to create documentation:
inspect(&Module.foo/1) is "&Module.foo/1" whereas
inspect(fn x -> Module.foo(x) end) is "#Function<6.127694169/1 in :erl_eval.expr/5>".
Thanks! ![]()
Trending in Questions
Other Trending 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
- #blog-post
- #phoenix_html
- #iex
- #ai
- #graphql
- #genstage
- #elixirconf-us
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #metaprogramming
- #security
- #hex











Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
OvermindDL1
Would not
&apply(Confy.Parsers, parser, [&1])work?apply/3is so very useful. ^.^Consequently it has no speed hit over a normal indirect call either since they lower to the same beam code, just to be sure I’ve also benchmarked it. ^.^
OvermindDL1
Also instead of this, this is faster:
Qqwy
Using
function_exported?is definitely the way to go. Thank you, I did not know about that function!As for using
apply: It would end up in the documentation as well:See f.e. here:
this would then become
which is not nearly as nice.
Thus I really am looking for a way to construct
&SomeModule.foo/1wherefoois a dynamic value.If there is no way around sing
.
Code.eval_quotedthen that is fine, but I did want to checkhauleth
Function.capture/3is what you are looking for.axelson
Wow, there’s so many little goodies in the stdlib. Never ceases to amaze me.