Reputation: 195
If you have a module, for instance
defmodule Foo do
# lots of "unknown" functions
end
How can I create a wrapper-module for that Foo
, like:
defmodule Bar do
# wrap all functions in Foo
end
But in Bar
I want to expose all functions in Foo
, but additionally I want to add some code in each function, specifically I want to try/catch
a specific error that can show up in any Foo.Error
exception... I'd like to do this without adding a function for each function in Foo
, since that will get repetetive.
Can I do this with macros?
Upvotes: 3
Views: 678
Reputation: 23556
With magic of metaprogramming everything is possible (however not always this makes sense):
defmodule Bar do
Code.ensure_compiled(Foo)
for {func, arity} <- Foo.__info__(:functions) do
args = Macro.generate_arguments(arity, __MODULE__)
def unquote(func)(unquote_splicing(args)) do
Foo.unquote(func)(unquote_splicing(args))
rescue
Foo.Error -> handle_error()
end
end
end
However this will not work for macros.
Upvotes: 1
Reputation: 2159
AFAIU you want to perform some kind of object-oriented programming by replicating the logic of inheritance between classes. But this is not the philosophy of any functional programming language like Elixir as you probably already know.
However, If this is really what you want to do, I found this question that uses metaprogramming and aim at doing something similar to what you are looking for. It looks complicated though.
Edit : After we had some further talk I understand your problem better. If you want to define function without too much repetition then metaprogramming is the way to go ! Here is a simple example on how to define several functions in a module thanks to metaprogramming :
defmodule MyModule do
Enum.each ~w(method1 method2), fn(method_name) ->
def unquote(:"#{method_name}")(), do: unquote(method_name)
end
end
I'd like to do this without adding a function for each function in Foo, since that will get repetetive.
I think that's what I would do, but are you sure it would be that repetitive ?
Also you can also use the Exceptional lib that will help you write less error-handling functions :)
Upvotes: 3
Reputation: 26812
This is a good use of defmacro, but definitely look into defedelegate as well. It lets you add(delegate) named references to functions in other/external modules.
Upvotes: 0