'How to write a macro whose body contains a user defined symbol?
I intend to create a macro that has the following behaviour:
@pass_symbol sym func
Expands to:
func(:sym)
The following experiments didn't yield any results:
macro pass_symbol(symarg, funcarg)
quote
$funcarg($symarg)
# turns into `func(sym)`
# which results in an error
# as `sym` is not defined
end
end
macro pass_symbol(symarg, funcarg)
quote
# combinations of
$funcarg($(Symbol(symarg)))
# or
$funcarg(Symbol(symarg))
# turns into `func(Symbol(sym))`
# which for the same reason detailed
# above results in an error
end
end
macro pass_symbol(symarg, funcarg)
quote
$funcarg(:$symarg)
# I wished to escape the ":"
# so that it would expand into func(:sym)
# but it didn't manage to
# evaluate `:` and `$` separately
end
end
I tried more shenanigans for sure. Eventually, I found this one:
macro pass_symbol(symarg, funcarg)
str = ":$symarg"
quote
$funcarg($(Meta.parse(str)))
end
end
But I'm not happy about it, as I feel like there must be a more idiomatic way to achieve this.
Please, feel free to suggest a more suiting title, as I couldn't find anything related using google and I want this to have good search-ability.
Solution 1:[1]
macro pass_symbol(symarg, funcarg)
quote
$funcarg($(Expr(:quote, (symarg))))
end
end
Or more concisely:
macro pass_symbol(symarg, funcarg)
quote
$funcarg($(QuoteNode(symarg)))
end
end
But I'm still not sure why QuoteNode achieves the desired behaviour following the documentation:
A quoted piece of code, that does not support interpolation. See the manual section about QuoteNodes for details.
Or if there's a way to solve this issue:
$funcarg(:$symarg)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
