How do I get the current script or class name in S

2020-04-10 14:03发布

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.

5条回答
仙女界的扛把子
2楼-- · 2020-04-10 14:14

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楼-- · 2020-04-10 14:23
// 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

查看更多
SAY GOODBYE
4楼-- · 2020-04-10 14:25
#!/bin/bash
exec scala "$0" "$0" "$@"
!#

val program = args(0)
println(program)
查看更多
Luminary・发光体
5楼-- · 2020-04-10 14:27

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)"
查看更多
该账号已被封号
6楼-- · 2020-04-10 14:34

I think this is the simplest:

val program = new Exception().getStackTrace.head.getFileName
查看更多
登录 后发表回答