我如何在scala中获取lineNumber,函数名称,pkg名称?

时间:2016-10-08 10:21:15

标签: scala playframework runtime

我试着谷歌搜索并搜索给我一些java例子......

Thread.currentThread().getStackTrace()(2).getLineNumber

但在worksheet总是返回 5 ,在工作项目scala/playframework 2.5中 - 总是 35

我尝试使用level,但它不起作用。

2 个答案:

答案 0 :(得分:1)

我明白了,例如创建services/Log.scala

package services

object Log {
  def info(text: String) = {
    val systemStr = makeSystemStr
    Console.out.println(Console.BLUE + "[INFO] " + systemStr + Console.RESET + text)
  }

  def makeSystemStr() = {
    val fileName = Thread.currentThread().getStackTrace()(3).getFileName
    val lineNumber = Thread.currentThread().getStackTrace()(3).getLineNumber
    val cnArr = Thread.currentThread().getStackTrace()(3).getClassName.split("[$]")
    val pkgName = cnArr(0).split("[.]")(0)
    val name = cnArr(0).split("[.]")(1)
    val defName = cnArr(3)
    s"$pkgName : $fileName : $name : $defName : line $lineNumber - "        
  }
}

然后在控制器中

package controllers

import play.api.mvc._
import services.Log

class SomeCtrl extends Controller {
  def Index = Action { request =>
    Log.info("some text")
    Ok("ok")
  }
}

答案 1 :(得分:1)

使用宏,您可以轻松获取lineNumber和fileName

//修改

import scala.language.experimental.macros
import scala.reflect.macros.blackbox

object SrcFile {

  def currentLine: Int = macro SrcFileImpl.currentLine

  def currentFileName: String = macro SrcFileImpl.currentFileName

  def currentPackage: String = macro SrcFileImpl.currentPackage

  def currentClassName: String = macro SrcFileImpl.currentClassName

  def currentFuncName :String = macro SrcFileImpl.currentFuncName
}

class SrcFileImpl(val c: blackbox.Context) {

  import c.universe._

  def getPackage(symbol: Symbol): String =
    if(symbol.isPackage) symbol.fullName else getPackage(symbol.owner)

  def getClass(symbol: Symbol): String =
    if(symbol.isClass) symbol.name.toTypeName.toString else getClass(symbol.owner)

  def currentPackage: c.Expr[String] = c.Expr(q"${getPackage(c.internal.enclosingOwner)}")

  def currentFileName: c.Expr[String] = c.Expr(q"${c.enclosingPosition.source.file.name}")

  def currentLine: c.Expr[Int] = c.Expr(q"${c.enclosingPosition.line}")

  def currentClassName: c.Expr[String] = c.Expr(q"${getClass(c.internal.enclosingOwner)}")

  def currentFuncName: c.Expr[String] = c.Expr(q"${c.internal.enclosingOwner.name.toTermName.toString}")

}

// test

package so


object SrcFileTest extends App {
  def f() = {

    println(SrcFile.currentFileName)
    println(SrcFile.currentLine)
    println(SrcFile.currentPackage)
    println(SrcFile.currentClassName)
    println(SrcFile.currentFuncName)
  }
  f()
}