tensor-programming
I’ve got a wrapper module that I am using around a library. The purpose of this module is to add small behavior to the library without outright forking it. I have a macro that produces the appropriate defdelegate and defoverridable calls on all of the functions that I need from library but I find myself writing a ton of boilerplate that could probably also be in the macro.
I have a struct called LibraryWrapper that looks like this:
defstruct type: Library.new(...)
For 1 arity functions I have a generalization that looks like this:
alias LibraryWrapper, as: LW
def foo(%LW{type: type}), do: Library.foo(type)
defdelegate foo(type), to: Library
For 2 arity functions, I have a generalization that looks like this:
alias LibraryWrapper, as: LW
def bar(%LW{type: type_a}, %LW{type: type_b}), do: Library.bar(type_a, type_b)
def bar(type_a, %LW{type: type_b}), do: Library.bar(type_a, type_b)
def bar(%LW{type: type_a}, type_b), do: Library.bar(type_a, type_b)
defdelegate(type_a, type_b), to: Library
If there were higher arity functions, the pattern would continue (but there aren’t for this particular library). Heres what the macro I am using looks like currently; and as you will see the defdelegate calls inside of it are completely irrelevant because the overridden functions override these making it so that they will never match. But if I could add a general pattern for all arity functions before the defdelegate call then I could just use the macro and not write all of the boilerplate.
defmacro wrap(module) do
module= Macro.expand(module, __CALLER__)
functions = module.__info__(:functions)
sigs =
Enum.map(functions, fn {name, arity} ->
args =
if arity == 0 do
[]
else
Enum.map(1..arity, fn i ->
{String.to_atom(<<?A + i - 1>>), [], nil}
end)
end
{name, [], args}
end)
combined = List.zip([sigs, functions])
for comb <- combined do
quote do
defdelegate unquote(elem(comb, 0)), to: unquote(module)
defdelegate unquote([elem(comb, 1)])
end
end
end
Where I am running into issues is trying to figure out how to build the AST for getting the field out of the struct that I plan to pass into the macro. Also, I am not entirely sure how to build AST where the function matches on the specific struct type as I am doing above. I also have to wonder if there is a better way to do this apart from making a struct wrapper.
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
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixir-ls
- #elixirconf-us
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
tensor-programming
Was able to figure it out with a pretty janky macro. But at least it seems to work in this case:
I know this can be cleaned up significantly but at least it works for my purposes.