在没有灵性的情况下确保卫生

时间:2012-04-23 09:16:47

标签: scala

使用reifyeval在Scala中编写卫生宏很容易。但it's not always possible要使用reifyeval

所以,如果一个人不能使用它们,那么确保宏是卫生的规则是什么?有没有办法测试一个宏,以确保没有不良卫生已经穿过裂缝?

UPD。在2.10.0的后期里程碑中,Expr.eval已重命名为Expr.splice

2 个答案:

答案 0 :(得分:10)

Reify是卫生的,因为它可以与Ident和This树一起保存符号。

如果您的宏扩展结果没有附加到idents的符号(例如,您只有Ident(“x”)来指定对名为x的引用的引用),那么宏扩展的后续类型检查将x绑定到任何是在调用站点的范围内(或者如果该范围没有x,则会出现编译错误。)

相比之下,当您的宏扩展具有其标识符号时,类型标记符不会尝试重新解析它们,而只是使用它具有的内容。这意味着当您重新表达一个表达式并在宏扩展中使用结果时,它会将其符号带入调用站点。好吧,不是所有符号,例如不可能引用局部变量或私有/受保护的东西,但是对全局可访问的声明的引用是持久的。

底线是检查您的宏是否卫生,检查您的idents和thises是否附有符号。您可以通过重新生成或手动将符号分配给手工制作的树来实现此目的。

答案 1 :(得分:1)

由于reify是一个宏,我只是看看它的实现,以找出它的作用。