Last active
February 21, 2016 08:52
-
-
Save BjRo/d4cb763d9b3e8c927c18 to your computer and use it in GitHub Desktop.
Trying to unquote a map from a macro does not compile
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Test do | |
defmacro __using__(opts) do | |
quote do | |
import unquote(__MODULE__), only: [map_test: 0] | |
end | |
end | |
#works as expected | |
defmacro map_test do | |
bar = [foo: "bar"] | |
quote do | |
def foo do | |
unquote(bar) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule Test do | |
defmacro __using__(opts) do | |
quote do | |
import unquote(__MODULE__), only: [map_test: 0] | |
end | |
end | |
# This fails to compile with | |
# Compiled lib/test.ex | |
# ** (CompileError) test/test_test.exs: invalid quoted expression: %{foo: "bar"} | |
# test/test_test.exs:5: (module) | |
defmacro map_test do | |
bar = %{ :foo => "bar" } | |
quote do | |
def foo do | |
unquote(bar) | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
defmodule TestTest do | |
use ExUnit.Case | |
defmodule TestHelper do | |
use Test | |
map_test | |
end | |
test "content is properly inlined" do | |
IO.inspect TestHelper.foo | |
end | |
end |
The solution is
defmodule Test do
defmacro map_test do
bar = %{ :foo => "bar" } |> Macro.escape
quote do
def foo do
unquote(bar)
end
end
end
end
See http://elixir-lang.org/getting-started/meta/quote-and-unquote.html#escaping for more infos
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm a bit surprised that the everything is fine with the keyword version, but the map version doesn't compile. What am I missing here? Is there an Elixir behavior/constraint that explains this?