Open anykeyh opened 6 years ago
@anykeyh It would be fixed in next release. As a workaround you can use this.
"%s#%s" % [{{a.id}}, {{b.id}}]
Better workaround for performance:
macro do_something(a, b)
"#{{{a.id}}}##{{{b.id}}}"
end
puts do_something("1", "2") # puts "1#2"
Better workaround for performance again! (nothing at runtime):
macro do_something(a, b)
"{{a.id}}{{'#'.id}}{{b.id}}"
end
puts do_something "1", "2" # => "1#2"
Having stumbled across this issue, I find it only intuitive that "#{{foo}}"
is interpreted as a macro expansion prefixed by #
and not string interpolation of a tuple. Macro expressions are on a higher level than other code so they should have precedence.
So #5288 is IMO wrong as it provides a workaround for what should be valid by default.
Why is this closed? It's still a valid issue.
Sorry, mistake of mine, I thought it has been fixed long time ago 👎
There is another solution: We could completely disable macro expansion inside literals. I don't think that is a necessary feature. There doesn't even seem to be a spec for that, so maybe it's something that just happens to be but nobody really thought about it?
The thing is: There are currently two types of expansions in string literals: string interpolation (#{}
) and macro expansion ({{}}
). The latter is rarely talked about and probably many developers are not aware of it. It is still applied in some occasions in stdlib and probably also in shards.
If macro expansions were removed from literals, it would make the language a bit simpler. They can easily be replaced by interpolation, either as a macro or at runtime.
# macro expansion
"foo {{ bar.id }}"
# macro string interpolation
{{ "foo #{bar.id}" }}
# runtime interpolation
"foo #{ {{ bar }} }"
The latter has a small performance impact because the string is composed at runtime. But that can be mitigated by using a macro string interpolation. Apart from that, all three variants should be equivalent.
Parser got wrong while parsing macro with string
This will fail to compile, as macro will ignore
#{{b.id}}
However I'm not sure I'm doing it right. I've tried with different position of backslashes
\
to escaping it, but nothing is working.