Groovy中的__LINE__功能

时间:2012-02-23 04:10:26

标签: groovy

可以在Ruby或Perl中通过__LINE__获取当前行号。 例如:

print "filename: #{__FILE__}, line: #{__LINE__}"

Groovy中是否有相同的功能?

2 个答案:

答案 0 :(得分:3)

不直接,但您可以通过Exception(或Throwable)堆栈跟踪获取它。例如:

 StackTraceElement getStackFrame(String debugMethodName) {
     def ignorePackages = [
         'sun.',
         'java.lang',
         'org.codehaus',
         'groovy.lang'
     ]
     StackTraceElement frame = null
     Throwable t = new Throwable()
     t.stackTrace.eachWithIndex { StackTraceElement stElement, int index ->
         if (stElement.methodName.contains(debugMethodName)) {
             int callerIndex = index + 1
             while (t.stackTrace[callerIndex].isNativeMethod() ||
                    ignorePackages.any { String packageName ->
                        t.stackTrace[callerIndex].className.startsWith(packageName)
                    }) {
                 callerIndex++
             }
             frame = t.stackTrace[callerIndex]
             return
         }
     }
     frame
 }

 int getLineNumber() {
     getStackFrame('getLineNumber')?.lineNumber ?: -1
 }

 String getFileName() {
     getStackFrame('getFileName')?.fileName
 }

 String getMethodName() {
     getStackFrame('getMethodName')?.methodName
 }

 def foo() {
     println "looking at $fileName:$lineNumber ($methodName)"
 }

 foo()

 // ==> looking at test.groovy:39 (foo)

但请注意:获取行号,文件名或类似方法非常慢。

答案 1 :(得分:1)

我不是Groovy的专家,但我不这么认为。我知道Java和C#没有它。

__LINE__功能真正开始帮助在C中进行调试.C没有现代语言的异常或许多其他功能,但它确实有编译器可以扩展到代码中的任何地方的宏,这就是为什么我们需要__FILE____LINE__等让我们知道发生了什么事情时的情况。这就是assert在C和C ++中的工作方式。 JVM具有非常好的调试工具,结合assert和异常,您可以非常轻松地找出出错的地方(堆栈跟踪总是比线号更好)。

我相信Ruby和Perl拥有这些宏的原因是因为它们是由C黑客创建的。我从来没有使用过这两种语言,足以知道调试支持的级别或者宏的实用程度。