如何在Scala中获取当前脚本或类名?

时间:2011-11-14 22:34:24

标签: class scala filenames

我希望我的Scala程序能够以编程方式确定其脚本文件名或其类名,将字符串存储在变量program中并打印出名称。

Java有several方法。

5 个答案:

答案 0 :(得分:3)

我认为这是最简单的:

val program = new Exception().getStackTrace.head.getFileName

答案 1 :(得分:2)

如0__所暗示的那样解析堆栈跟踪应该处理大多数用例,特别是当使用main方法的对象不在同名文件中时:

package utils

trait ProgramInfo {
  val programInfo = try { 
    throw new RuntimeException("x")
  } catch { 
    case e: RuntimeException =>
      val arr = new java.io.CharArrayWriter()
      val buffer = new java.io.PrintWriter(arr)
      e.printStackTrace(buffer)
      val trace = arr.toString 
      val lines = io.Source.fromString(trace)
      val pat = """^.*at.*\.main\(([^:]*)(:.*)?\).*$""".r
      lines.getLines().collectFirst{case pat(n, l) => n}.getOrElse("<none>")
  }
}

object ProgramInfo extends ProgramInfo

然后你这样称呼:

println(utils.ProgramInfo.programInfo)

或者您混入主要对象

object A extends utils.ProgramInfo {
   def main(args: Array[String]) {
     println(programInfo)
   }
}

这适用于脚本scala A.script,无论代码是否包装在对象中。使用scalac进行编译并以scala A运行时也可以使用此功能。使用REPL运行时,将返回<none>

答案 2 :(得分:1)

不完全确定你在找什么......

$ scala -e 'println( "I am " + getClass.getName )'

给了我

"I am Main$$anon$1"

$ scala -e 'try { sys.error( "" )} catch { case e => println( "I am " + e.getStackTrace()( 3 ))}'

给了我

"I am Main.main(scalacmd2873893687624153305.scala)"

答案 3 :(得分:1)

// With help from huynhjl
// http://stackoverflow.com/questions/8129185#8131613

import scala.util.matching.Regex.MatchIterator

object ScriptName {
    val program = {
        val filenames = new RuntimeException("").getStackTrace.map { t => t.getFileName }
        val scala = filenames.indexOf("NativeMethodAccessorImpl.java")

        if (scala == -1)
            "<console>"
        else
            filenames(scala - 1)
    }

    def main(args: Array[String]) {
        val prog = program
        println("Program: " + prog)
    }
}

Rosetta Code

答案 4 :(得分:0)

#!/bin/bash
exec scala "$0" "$0" "$@"
!#

val program = args(0)
println(program)