2016-04-14 6 views
0

У меня есть макрос, который я хочу использовать для регистрации времени, которое требуется, чтобы выполнить блок, который может вернуть что-то полезноеScala макрос с новым идентификатором

, так что если у меня есть что-то вроде

вал у = Р (х)

Я изменю к

валь у = Timed (ф (х))

И получите время, которое потребовалось, чтобы выполнить функцию в журнале.

Я почти есть то, что я хочу, но при использовании свежих термин имен, чтобы избежать столкновения имя, например, между t0 и t1, я получаю сообщение об ошибке:

Error:(22, 15) Can't unquote reflect.runtime.universe.TermName, consider providing an implicit instance of Liftable[reflect.runtime.universe.TermName] 
     val $kk = System.nanoTime() 
     ^

Как получить эти freshTermNames работы с квазиквартины?

import scala.language.experimental.macros 
import scala.reflect.macros.blackbox.Context 
import scala.reflect.runtime.{ universe ⇒ u } 

object Timed { 
    def apply[T](block: ⇒ T): T = macro Timed.apply_impl[T] 

    def apply_impl[T: c.WeakTypeTag](c: Context)(block: c.Expr[T]): c.Expr[T] = { 
    import c.universe._ 
    implicit val cc: c.type = c 
    val kk = u.internal.reificationSupport.freshTermName("kk") 
    val t0 = c.freshName("t0") 
    val t1 = c.freshName("t1") 
    val tdiff = c.freshName("tdiff") 
    val blk = c.freshName("blk") 
    val t0n = "t0" 
    println(t0) 
    val res = c.Expr(
     q""" 
     val $kk = System.nanoTime() 
     $block 
     val t1 = System.nanoTime() 
     val tdiff= t1 - t0 
     log.debug("Took: {}", tdiff) 
     $block 
     """) 
    println("Timing block: ") 
    println(show(res)) 
    res 
    } 
} 

ответ

0

Вы не хотите TermName, вы хотите, чтобы Ident:

val kk = Ident(TermName("kk")) 

Но если имя идентификатора является постоянным, нет никаких оснований даже построить идентификатор, как это, когда вы бы только что написали:

q""" 
    val kk = System.nanoTime 
    ... 
""" 

Изменение, которое исправит эту проблему, но есть и другие. t0 не определено в квазикварталах, и все остальные имена терминов, которые вы определили, фактически ничего не делают.

Я не понимаю, зачем вам нужен макрос для этого, когда обычный метод делает работу просто отлично. Макрос увеличит размер вашего кода (значительно, если вы его много используете).

Смежные вопросы