Как я могу получить lineNumber, имя функции, имя pkg в scala?

#scala #playframework #runtime

#scala #playframework #время выполнения

Вопрос:

Я пытаюсь найти его в Google и поиск дает мне только примеры Java…

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

но в worksheet всегда возвращается 5, а в рабочем проекте scala/playframework 2.5 — всегда 35

Я пытаюсь поиграть level , но это не работает.

Комментарии:

1. github.com/lihaoyi/sourcecode

Ответ №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")
  }
}
  

Ответ №2:

используйте макрос, вы можете легко получить номер строки и имя файла

// редактировать

 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}")

}
  

// тест

 package so


object SrcFileTest extends App {
  def f() = {

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

Комментарии:

1. итак, что насчет имени pkg, имени класса и имени функции?