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

发布于 2024-12-15 06:13:52 字数 181 浏览 3 评论 0原文

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

Java 有几种 方法来实现此目的。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

魂牵梦绕锁你心扉 2024-12-22 06:13:52

我认为这是最简单的:

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

I think this is the simplest:

val program = new Exception().getStackTrace.head.getFileName
表情可笑 2024-12-22 06:13:52

按照 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)

或者您混合到您的main object

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

这适用于脚本 scala A.script,无论代码是否包装在对象中。当使用 scalac 编译并作为 scala A 运行时,这也适用。当使用 REPL 运行时,将返回

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>.

静谧 2024-12-22 06:13:52

不太确定你在寻找什么......

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

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)"
久伴你 2024-12-22 06:13:52
// 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 代码

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

oО清风挽发oО 2024-12-22 06:13:52
#!/bin/bash
exec scala "$0" "$0" "$@"
!#

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

val program = args(0)
println(program)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文