问题
I'd like my Scala program to be able to programmatically determine either its script filename or its class name, store the string in a variable program
and print out the name.
Java has several methods for this.
回答1:
I think this is the simplest:
val program = new Exception().getStackTrace.head.getFileName
回答2:
Parsing the stack trace as hinted by 0__ should take care of most of the use cases, in particular when the object with the main method is not in a file of the same name:
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
Then you call this like that:
println(utils.ProgramInfo.programInfo)
or you mix in into your main object
object A extends utils.ProgramInfo {
def main(args: Array[String]) {
println(programInfo)
}
}
This works for scripts scala A.script
whether the code is wrapped in an object or not. This also works when compiled with scalac
and run as scala A
. When run with the REPL, this will return <none>
.
回答3:
Not exactly sure what you are looking for...
$ scala -e 'println( "I am " + getClass.getName )'
gives me
"I am Main$$anon$1"
And
$ scala -e 'try { sys.error( "" )} catch { case e => println( "I am " + e.getStackTrace()( 3 ))}'
gives me
"I am Main.main(scalacmd2873893687624153305.scala)"
回答4:
// 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
回答5:
#!/bin/bash
exec scala "$0" "$0" "$@"
!#
val program = args(0)
println(program)
来源:https://stackoverflow.com/questions/8129185/how-do-i-get-the-current-script-or-class-name-in-scala