Hi, could someone explain to me what I’m doing wrong here. I’m trying to pattern match on a defmacro
arguments.
Basically I have this:
defmacro div_with_content(content, body, socket, el_id, chain, el_contents) do
quote do
content_tag(:div, Phoenix.HTML.raw(
"#{unquote(content)}#{(
for {id, contents} <- unquote(body) do
safe_to_string(live_render(unquote(socket), Cocktail.Element, session: %{section: :div, contents: contents, id: id, chain: [unquote(el_id) | unquote(chain)]}, child_id: id))
end)}"
),
[
{:cocktail, 1},
{:id, unquote(el_id)},
{:"cocktail-chain", Jason.encode!(:lists.reverse(unquote(chain)))}
| Map.get(unquote(el_contents), :attrs, [])
]
)
end
end
This one works fine. Now I was trying to refactor all the functions for divs into a single one with multiple macro definitions, the equivalent to this one would be (there are other 2 with the same name, different patterns):
defmacro cocktail_tag(
%{
tag: :div,
body: [_|_] = body,
content: content,
attrs: attrs,
style: style,
classes: classes,
interactions: _interactions
},
socket, el_id, chain) do
quote do
content_tag(:div, Phoenix.HTML.raw(
"#{unquote(content)}#{(
for {id, contents} <- unquote(body) do
safe_to_string(live_render(unquote(socket), Cocktail.Element, session: %{section: :div, contents: contents, id: id, chain: [unquote(el_id) | unquote(chain)]}, child_id: id))
end)}"
),
add_attributes_list(el_id, chain, attrs, style, classes)
)
end
end
But when I try to use the last one, I get:
== Compilation error in file lib/cocktail_web/views/page_view.ex ==
** (FunctionClauseError) no function clause matching in CocktailWeb.LayoutView.cocktail_tag/4
(cocktail) expanding macro: CocktailWeb.LayoutView.cocktail_tag/4
(cocktail) lib/cocktail_web/templates/page/editor_element.html.leex:6: CocktailWeb.PageView."editor_element.html"/1
(phoenix) /Users/mnussbaumer/code/cocktail/lib/cocktail_web/views/page_view.ex:1: Phoenix.Template.__before_compile__/1
(elixir) lib/kernel/parallel_compiler.ex:206: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/6
So I’m wondering if it’s impossible to do this? What is wrong with my approach?