Reputation: 590
I'm trying to define a function based on a already defined function on a module.
I want to do something like this:
defmodule A do
def my_func(pid, arg1, arg2) do
send pid, "Do Something"
end
end
And after my_func is defined, I would like to define my_func(arg1, arg2)
that calls my_func
passing a pid that I'll get from a pool of pids for example.
My first attempt was using @on_definition but I had no success. Then I tried doing this inside the module:
Enum.each Module.definitions_in(__MODULE__, :def), fn {func_name, arity} ->
args = Enum.map(0..arity-1, fn i -> "arg_#{i}" end)
quoted = quote do
def unquote(func_name)(unquote_splicing(args)) do
....
But still I'm not having success. Anyone have any idea on how do I get this? :)
Upvotes: 1
Views: 209
Reputation: 6059
Actually, the solution by bitwalker can be simplified. You don't need to quote and do eval_quoted
, since def
is a macro that injects directly into AST. So this will work as well:
defmodule Test do
def my_func(pid, arg1, arg2) do
send pid, {arg1, arg2}
end
Enum.map Module.definitions_in(__MODULE__, :def), fn {func_name, _arity} ->
def unquote(func_name)(arg1, arg2) do
pid = :some_pid
unquote(func_name)(pid, arg1, arg2)
end
end
Enum.each Module.definitions_in(__MODULE__, :def), fn {func_name, arity} ->
IO.inspect {func_name, arity}
end
end
Upvotes: 3
Reputation: 9261
You can accomplish this like so:
defmodule Test do
def my_func(pid, arg1, arg2) do
send pid, {arg1, arg2}
end
quoted = Enum.map Module.definitions_in(__MODULE__, :def), fn {func_name, _arity} ->
quote do
def unquote(func_name)(arg1, arg2) do
pid = :some_pid
unquote(func_name)(pid, arg1, arg2)
end
end
end
Module.eval_quoted(__MODULE__, quoted)
Enum.each Module.definitions_in(__MODULE__, :def), fn {func_name, arity} ->
IO.inspect {func_name, arity}
end
end
If you compile this with elixirc test.ex
, you'll see it spit out the definitions for my_func/2
and my_func/3
. The problem with your initial code was that while you were mapping over and quoting the definitions, you never evaluated those quoted expressions, so they were not compiled as part of your module.
Upvotes: 3