Как получить текущее script или имя класса в Scala?

Мне бы хотелось, чтобы моя программа Scala могла программно определить либо ее имя файла script, либо его имя класса, сохранить строку в переменной program и распечатать имя.

Java имеет несколько методов для этого.

5 ответов

// With help from *******
// 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)
 }
}
</console>

Rosetta Code


Я думаю, что это самое простое:

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


Анализ трассировки стека, намеченный на 0__, должен позаботиться о большинстве случаев использования, в частности, когда объект с основным методом не находится в файле с тем же именем:

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
</none>

Затем вы вызываете это следующим образом:

println(utils.ProgramInfo.programInfo)

или вы перемещаетесь в свой основной объект

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

Это работает для скриптов scala A.script, заключен ли код в объект или нет. Это также работает при компиляции с scalac и выполняется как scala A. При запуске с REPL это вернет .


Не совсем уверен, что вы ищете...

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


#!/bin/bash
exec scala "$0" "$0" "$@"
!#
val program = args(0)
println(program)

licensed under cc by-sa 3.0 with attribution.