loggingScala 2.10macros
我将从一个例子开始。 这里有一个相当于List.fill
的元组作为Scala 2.10中的一个macros:
import scala.language.experimental.macros import scala.reflect.macros.Context object TupleExample { def fill[A](arity: Int)(a: A): Product = macro fill_impl[A] def fill_impl[A](c: Context)(arity: c.Expr[Int])(a: c.Expr[A]) = { import c.universe._ arity.tree match { case Literal(Constant(n: Int)) if n < 23 => c.Expr( Apply( Select(Ident("Tuple" + n.toString), "apply"), List.fill(n)(a.tree) ) ) case _ => c.abort( c.enclosingPosition, "Desired arity must be a compile-time constant less than 23!" ) } } }
我们可以使用这个方法如下:
scala> TupleExample.fill(3)("hello") res0: (String, String, String) = (hello,hello,hello)
这家伙在几个方面是一只奇怪的鸟。 首先, arity
参数必须是一个整数,因为我们需要在编译时使用它。 在以前的Scala版本中,对于一个方法来说,没有办法(据我所知)甚至不知道它的一个参数是否是编译时的文字。
其次, Product
返回types是一个谎言 – 静态返回types将包含由参数确定的特定元素和元素types,如上所示。
那么我将如何logging这件事? 在这一点上,我并不期待Scaladoc的支持,但是我希望有一个约定或者最佳实践的意义(除了确保编译时错误信息是清晰的),这将使得运行在macros观方法上潜在的离奇的需求 – 对于Scala 2.10库的用户而言更不令人意外。
新的macros观系统(例如, ScalaMock , Slick , 这里列出的其他系统)的最成熟的演示在方法层面上还是相对没有文档的。 任何示例或指针将不胜感激,包括来自其他语言与类似的macros系统。
我认为logging这些文件的最好方法是使用示例代码,正如迈尔斯在他不成形的基于macros观的实验分支中所做的那样。