__LINE__ особенность в Groovy - PullRequest
       4

__LINE__ особенность в Groovy

6 голосов
/ 23 февраля 2012

Можно получить текущий номер строки по __LINE__ в Ruby или Perl.Например:

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

Есть ли такая же функция в Groovy?

Ответы [ 2 ]

3 голосов
/ 23 февраля 2012

Не напрямую, но вы можете получить его через трассировку стека исключений (или 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 голос
/ 23 февраля 2012

Я не специалист в Groovy, но я так не думаю. Я знаю, что в Java и C # его нет.

Функция __LINE__ действительно начала помогать с отладкой в ​​C. В C нет исключений или многих других функций, которые есть в современных языках, но в ней есть макросы, которые компилятор может развернуть в любом месте кода, что почему нам нужны __FILE__, __LINE__ и т. д., чтобы сообщить нам, где мы были, когда случилось что-то плохое. Вот как assert работает в C и C ++. JVM имеет очень хорошие средства отладки, и в сочетании с assert и исключениями вы очень легко можете определить, где что-то пошло не так (трассировки стека в любом случае намного лучше, чем просто номер строки).

Я полагаю, что причина того, что Ruby и Perl имеют эти макросы, заключается в том, что они были созданы хакерами Си. Я никогда не использовал ни один из этих языков настолько, чтобы узнать уровень поддержки отладки или насколько полезны макросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...