隐式提取Scala函数名和参数
我有以下代码:隐式提取Scala函数名和参数,scala,playframework,Scala,Playframework,我有以下代码: def disableRules(someId: String) = Action.async { implicit req => Metrics.measureTime("disableRules") { someFutureOpr(someId).map(_ => Ok) .recover { case e: Exception => handlerError(s"Failure occu
def disableRules(someId: String) = Action.async { implicit req =>
Metrics.measureTime("disableRules") {
someFutureOpr(someId).map(_ => Ok)
.recover {
case e: Exception => handlerError(s"Failure occurred on disableRules request ${e.getMessage}", "disableRules")
}
}
}
def activeRules(someId: String) = Action.async { implicit req =>
Metrics.measureTime("activeRules") {
someFutureOpr2(someId).map(_ => Ok)
.recover {
case e: Exception => handlerError(s"Failure occurred on activeRules request ${e.getMessage}", "activeRules")
}
}
}
...
如您所见,我有mesureTime和handleError函数,我将函数名作为字符串传递给它们,是否有方法隐式传递,我的意思是它将采用函数名,如果没有-有方法提取函数名并打印它,还涉及参数。在度量中计算它:
例如:
def a1() = {
Metrics.measureTime()
}
def a2() = {
Metrics.measureTime()
}
将输出:
a1
a2
这是一次安全的手术吗?
如果我们有:
def currentMethodName() : String = Thread.currentThread.getStackTrace.toList.mkString("\n")
我们得到:
java.lang.Thread.getStackTrace(Thread.java:1559)
HelloWorld1$Metrics$.currentMethodName(HelloWorld1.scala:69)
HelloWorld1$Metrics$.measureTime(HelloWorld1.scala:72)
HelloWorld1$.a1(HelloWorld1.scala:77)
HelloWorld1$.main(HelloWorld1.scala:103)
HelloWorld1.main(HelloWorld1.scala)
因此,我们看到:
在索引0中,我们得到getStackTrace。
在索引1中,我们有currentMethodName。
在指标2中,我们有度量时间。
因为measureTime不是堆栈跟踪的第一个方法,所以我们必须确保堆栈跟踪中有另一个元素。因此,在您的情况下,是的,它是安全的。在度量中计算它:
例如:
def a1() = {
Metrics.measureTime()
}
def a2() = {
Metrics.measureTime()
}
将输出:
a1
a2
这是一次安全的手术吗?
如果我们有:
def currentMethodName() : String = Thread.currentThread.getStackTrace.toList.mkString("\n")
我们得到:
java.lang.Thread.getStackTrace(Thread.java:1559)
HelloWorld1$Metrics$.currentMethodName(HelloWorld1.scala:69)
HelloWorld1$Metrics$.measureTime(HelloWorld1.scala:72)
HelloWorld1$.a1(HelloWorld1.scala:77)
HelloWorld1$.main(HelloWorld1.scala:103)
HelloWorld1.main(HelloWorld1.scala)
因此,我们看到:
在索引0中,我们得到getStackTrace。
在索引1中,我们有currentMethodName。
在指标2中,我们有度量时间。
因为measureTime不是堆栈跟踪的第一个方法,所以我们必须确保堆栈跟踪中有另一个元素。因此,在您的情况下,是的,它是安全的。您可以使用宏而不使用运行时反射来解决此问题:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class CaptureImpl(val c: blackbox.Context) {
import c.universe._
def describe[T: c.WeakTypeTag](
expr: c.Expr[T]
): c.Expr[String] = c.Expr[String](q"(${expr.tree.toString()})")
}
object CaptureMethod {
def apply[T](expr: T): String = macro CaptureImpl.describe[T]
}
例如:
object Test {
def foo(): String = "hello"
def bar(a: Int): Int = a
def baz(s: String): String = s
def main(args: Array[String]): Unit = {
println(CaptureMethod(foo()))
println(CaptureMethod(bar(1)))
println(CaptureMethod(baz("yes")))
}
}
收益率:
Test.this.foo()
Test.this.bar(1)
Test.this.baz("yes")
您可以使用宏而不使用运行时反射来解决此问题:
import scala.language.experimental.macros
import scala.reflect.macros.blackbox
class CaptureImpl(val c: blackbox.Context) {
import c.universe._
def describe[T: c.WeakTypeTag](
expr: c.Expr[T]
): c.Expr[String] = c.Expr[String](q"(${expr.tree.toString()})")
}
object CaptureMethod {
def apply[T](expr: T): String = macro CaptureImpl.describe[T]
}
例如:
object Test {
def foo(): String = "hello"
def bar(a: Int): Int = a
def baz(s: String): String = s
def main(args: Array[String]): Unit = {
println(CaptureMethod(foo()))
println(CaptureMethod(bar(1)))
println(CaptureMethod(baz("yes")))
}
}
收益率:
Test.this.foo()
Test.this.bar(1)
Test.this.baz("yes")
这回答了你的问题吗?它并没有涵盖一切,有没有办法让messureTime和handleError隐式地获得这个值?还有,如果有什么方法可以服用parmsDoes,请回答您的问题?它并没有涵盖一切,有没有办法让messureTime和handleError隐式地获得这个值?还有,如果有什么方法可以使用parmsNice!如何从恢复中隐式发送CaptureMethod?在我的代码中question@ZviMints您希望在recover中具体执行什么操作?我希望调用handleError,同时使用或不使用其他字段[在这种情况下,隐式处理],这些字段可以打印本例中的调用方函数-disableRulessomeId或activeRulessomeId@ZviMints我懂了,这会有点棘手,因为我们需要传入调用函数ATM,我不确定宏是否可以隐式地推断它所在的上下文。是否有其他方法在编译时获取数据?很好!如何从恢复中隐式发送CaptureMethod?在我的代码中question@ZviMints您希望在recover中具体执行什么操作?我希望调用handleError,同时使用或不使用其他字段[在这种情况下,隐式处理],这些字段可以打印本例中的调用方函数-disableRulessomeId或activeRulessomeId@ZviMints我懂了,这会有点棘手,因为我们需要传入调用函数ATM,我不确定宏是否可以隐式推断它所在的上下文。是否有其他方法在编译时获取数据?我找不到相关的堆栈跟踪,因为它来自恢复method@ZviMints可以使用另一种解决方案。这是一个很好的解决办法。出现这种行为的原因是在recover部分中调用了currentMethodName。您应该在Metrics.measureTime.executely之前调用它,但这样我就可以打印函数的名称,我想在恢复时隐式地传递它,messureTime对我来说不太重要。我找不到相关的堆栈跟踪,因为它来自恢复method@ZviMints可以使用另一种解决方案。这是一个很好的解决办法。出现这种行为的原因是在recover部分中调用了currentMethodName。您应该在Metrics.measureTime.executely之前调用它,但这样我就可以打印函数的名称,我想在恢复时隐式地传递它,而messureTime对我来说不那么重要。