Disclaimer: I know that it's possible to write code in a simpler manner, but you should understand that I post simplified code to SO.
I have a module Simple
which uses Included
:
defmodule Simple do
use Included,
events: [
[
name: :start,
callback: fn(x) -> x * 2 end
], [
name: :finish,,
callback: fn(x) -> x * 3 ; x end
]
]
end
I want Included
module to define a function which takes one param for each item in the list above and return a value. So, I'm doing this:
defmodule Included do
defmacro __using__(opts)
events = Keyword.get(opts, :events)
quote bind_quoted: [events: events] do
events
|> Enum.each(fn(event) ->
def unquote(event[:name])(x) do
x
|> unquote(event[:callback]).()
|> IO.puts
end)
end
end
end
The problem here is that I receive invalid quoted expression: #Function<0.105634730
. I tried to implement it another way:
defmodule Included do
defmacro __using__(opts)
events = Keyword.get(opts, :events)
events
|> Enum.each(fn(event) ->
quote bind_quoted: [event: event] do
def unquote(event[:name])(x) do
x
|> event[:callback].()
|> IO.puts
end
end
end)
end
end
But in this case I haven't seen functions defined. (No errors, there is no functions Simple.start/1
and Simple.finish/1
here).
My questions are:
- How can I define desired functions?
- Why did functions not defined in 2nd approach?
:callback
key of all events beforequote
:events = for event <- opts[:events] do; Keyword.update!(event, :callback, &Macro.escape/1); end
. – Dogbertcannot escape #Function<2.45959719/1 in Included.MACRO>. The supported values are: lists, tuples, maps, atoms, numbers, bitstrings, pids and remote functions in the format &Mod.fun/arity
I tried to implement something similar in iex, same result =( – asiniy