我希望我的Scala程序能够以编程方式确定其脚本文件名或其类名,将字符串存储在变量program
中并打印出名称。
Java有several方法。
答案 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)
}
}
答案 4 :(得分:0)
#!/bin/bash
exec scala "$0" "$0" "$@"
!#
val program = args(0)
println(program)