Можно получить номер текущей строки на __LINE__
в Ruby или Perl. Например:Функция __LINE__ в Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
Есть та же функция в Groovy?
Можно получить номер текущей строки на __LINE__
в Ruby или Perl. Например:Функция __LINE__ в Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
Есть та же функция в Groovy?
Не напрямую, но вы можете получить его через трассировку стека исключений (или 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)
Слово предостережения, хотя: получить номер строки, имя файла, или метод, как это очень медленно.
Я не эксперт в Groovy, но я так не думаю. Я знаю, что Java и C# этого не делают.
Функция __LINE__
действительно начала помогать с отладкой на C. C не имеет исключений или многих других функций, которые имеют современные языки, но у них были макросы, которые компилятор мог расширить в любом месте кода, а именно мы нуждались в __FILE__
, __LINE__
и т. д., чтобы сообщить нам, где мы были, когда случилось что-то плохое. Вот как работает assert
в C и C++. JVM имеет очень хорошие инструменты отладки и в сочетании с assert
и исключениями, вы можете легко определить, где что-то пошло не так (трассировка стека лучше, чем просто номер строки).
Я считаю, что причина, по которой Ruby и Perl имеют эти макросы, - это то, что они были созданы хакерами C. Я никогда не использовал ни один из этих языков, чтобы знать уровень поддержки отладки или насколько полезны макросы.
Я могу подтвердить, что они мало используются. Обычный способ получения информации о кадре в Perl, будь то внутри отладчика или вне его, заключается в использовании функции 'caller' с номером фрейма в качестве аргумента. 0, где вы сейчас находитесь, 1 - ваш вызывающий, 2 - его * вызывающий и т. Д. Теперь это возвращает пакет, имя файла, строку, подпрограмму и множество других вещей. Таким образом, вы обычно используете функциональный интерфейс для получения этой информации, а не старые псевдомакросы '__FILE__' и' __LINE__'. – tchrist
Почему это так медленно? Эквивалент в Perl (то есть через 'caller') очень быстр. – tchrist
Трассировки стека Java могут быть довольно глубокими, даже более хорошими. Метод [Throwable.fillInStackTrace] (http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#fillInStackTrace%28%29) занимает некоторое время, чтобы построить данные трассировки стека состав. Посмотрите http://stackoverflow.com/a/3980148/190201 для более глубокого изучения. Это, конечно, не слишком медленно использовать для отладки, но хорошо знать о его стоимости, прежде чем использовать его. – ataylor