Reputation: 7098
I'm messing around with macros in elixir purely for fun and not profit :). So I have a comma separated string and I want to dynamically create a function with that list as arguments i.e.
defmacro __using__(opts) do
args = "a,b,c"
quote do
def test(unquote(args)) do
IO.inspect("#{a},#{b},#{c}")
end
end
end
The problem I have is that the method created is: test("1,2,3")
and not test(1,2,3)
for obvious reasons. So how do I convert a string into a method argument?
Chris
Upvotes: 1
Views: 695
Reputation: 222428
There's probably a better way but one way to convert "a,b,c"
to something that can be injected into def
's argument list would be to use Code.string_to_quoted!/1
and unquote_splicing
:
defmacro __using__(_opts) do
args = "a,b,c"
args = Code.string_to_quoted!("[#{args}]")
quote do
def test(unquote_splicing(args)) do
IO.inspect(unquote(args))
end
end
end
Note that due to hygiene, you'll have to use args
to access the variables and you cannot directly access a
, b
, or c
inside the def.
Full Example:
defmodule Macros do
defmacro __using__(_opts) do
args = "a,b,c"
args = Code.string_to_quoted!("[#{args}]")
quote do
def test(unquote_splicing(args)) do
IO.inspect(unquote(args))
end
end
end
end
defmodule Main do
use Macros
def main do
test("a", "b", "c")
test(1, 2, 3)
end
end
Main.main
Output:
["a", "b", "c"]
[1, 2, 3]
Upvotes: 1