Sadece kaynak ve değer yazdırmak için doğrudan withSource
yeniden mümkün değildi ve değer döndürmek
Tree
için böyle Context
ait prefix
kullanabilirsiniz . withSource
makrosu, aynı nesnenin kendisinden kullanılamaz (bu yüzden, bu dosyada benim küçük bir değiştirilmiş sürümümüzü değiştiremiyorum) ve WithSourceHelper
alt sınıfından withSource
numaralı telefonu arayamıyorum, bu da miras yoluyla yeniden kullanılabilir.
Herkesin ilgisini çekmesi durumunda, Senia'nın cevabı yalnızca değeri kaynakla günlüğe kaydetme ve değeri geri döndürme işleminin geri kalanının gerçekleşmesi için geri göndermesi için bir tamamlayıcıdır.
def logValueImpl[T](c: Context): c.Expr[T] = {
import c.universe._
val source = c.prefix.tree match {
case Apply(_, List(s)) => s
case _ => c.abort(c.enclosingPosition, "can't find source")
}
val freshName = newTermName(c.fresh("logValue$"))
val valDef = ValDef(Modifiers(), freshName, TypeTree(source.tpe), source)
val ident = Ident(freshName)
val print = reify{
println(c.literal(show(source)).splice + ": " + c.Expr[T](ident).splice) }
c.Expr[T](Block(List(valDef, print.tree), ident))
}
Sonra def p = macro Debug.logValueImpl[T]
örtülü bir dönüşüm olarak tanımlar.
List(1, 2, 3).reverse.p.head
// prints: immutable.this.List.apply[Int](1, 2, 3).reverse: List(3, 2, 1)
komik kısmı iki kez uygulayabilirsiniz olmasıdır: Sonra bu gibi kullanabilirsiniz
List(1, 2, 3).reverse.p.p
Ve logValueImpl
makro ne yaptığını gösterecektir:
{
val logValue$7: List[Int] = immutable.this.List.apply[Int](1, 2, 3).reverse;
Predef.println("immutable.this.List.apply[Int](1, 2, 3).reverse: ".+(logValue$7));
logValue$7
}
Diğer makrolarla da çalışıyor gibi görünüyor:
f"float ${1.3f}%3.2f; str ${"foo".reverse}%s%n".p`
//prints:
{
val arg$1: Float = 1.3;
val arg$2: Any = scala.this.Predef.augmentString("foo").reverse;
scala.this.Predef.augmentString("float %3.2f; str %s%%n").format(arg$1, arg$2)
}: float 1.30; str oof%n
show
yerine showRaw
kullansaydım daha da ilginç bir şekilde, genişletilmiş makronun ağacını bile görebilirim, bu da diğer makroların nasıl yazılacağını anlamak için kullanışlı olabilir.
Şu kitaplıkta benzer işlevlerin (ve daha fazlasının) bulunduğunu öğrendim: https://github.com/retronym/macrocosm; 'log', 'trace', 'desugar' ... 'a bakın. – huynhjl