我想写一个简单的宏,显示名称&变量的值。在Common Lisp中,它将是
(defmacro dprint (&rest vars)
`(progn
,@(loop for v in vars
collect `(format t "~a: ~a~%" ',v ,v))))
在朱莉娅,我写了两个问题:
Expr
个对象收集到块中? (在Lisp中,这是通过将列表与,@
拼接到progn
来完成的。)我能想到的最好的方法是创建Expr(:block)
并设置其args
列表,但这远非优雅。$
,这会使问题复杂化,但即使我使用string
进行连接,我也无法打印变量的名称 - 至少:($v)
不会与CL ... {/ li>中的',v
相同
醇>
我当前的宏看起来像这样:
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println(string(:($v), " = ", $v))) for v in vars]
ex
end
观察宏观扩展显示了问题:
julia> macroexpand(:(@dprint x y))
quote
println(string(v," = ",x))
println(string(v," = ",y))
end
我想得到
quote
println(string(:x," = ",x))
println(string(:y," = ",y))
end
任何提示?
编辑:结合答案,解决方案似乎如下:
macro dprint(vars...)
quote
$([:(println(string($(Meta.quot(v)), " = ", $v))) for v in vars]...)
end
end
...即$(Meta.quot(v))
使用',v
,$(expr...)
使用,@expr
。再次感谢你!
答案 0 :(得分:7)
此@show
宏已存在。能够自己实现它是有帮助的,所以稍后你可以做其他的喜欢,比如make会显示一个数组的大小。
对于您的特定变体:
答案是Meta.quot
,
macro dprint(vars...)
ex = Expr(:block)
ex.args = [:(println($(Meta.quot(v)), " = ", $v)) for v in vars]
ex
end
见:
julia> a=2; b=3;
julia> @dprint a
a = 2
julia> @dprint a b
a = 2
b = 3
答案 1 :(得分:3)
,@x
的{{1}}(这是你问题的另一部分)。
例如,考虑宏
$(x...)
和调用
macro _begin(); esc(:begin); end
macro @_begin()(args...)
quote
$(args...)
end |> esc
end
(虽然可疑可读)产生预期结果@begin x=1 y=2 x*y
。 (2
宏不是示例的一部分;但它是必需的,因为@_begin
是保留字,因此需要宏来直接访问该符号。)
请注意
begin
我认为这比推送到julia> macroexpand(:(@begin 1 2 3))
quote # REPL[1], line 5:
1
2
3
end
数组更具可读性。