Es posible obtener el número de línea actual por __LINE__
en Ruby o Perl. Por ejemplo:__LINE__ función en Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
¿Existe la misma característica en Groovy?
Es posible obtener el número de línea actual por __LINE__
en Ruby o Perl. Por ejemplo:__LINE__ función en Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
¿Existe la misma característica en Groovy?
No directamente, pero puede obtenerlo a través de un rastro de pila de Excepción (o Arrojable). Por ejemplo:
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)
Una palabra de precaución sin embargo: obtener el número de línea, nombre de archivo o método como este es muy lento.
No soy un experto en Groovy, pero no lo creo. Sé que Java y C# no lo tienen.
La característica __LINE__
realmente comenzó a ayudar con la depuración en C. C no tiene excepciones ni muchas de las otras características que tienen los lenguajes modernos, pero sí tenía macros que el compilador podía expandir a cualquier parte del código, razón por la cual necesitábamos __FILE__
, __LINE__
, etc. para hacernos saber dónde estábamos cuando sucedía algo malo. Así es como funciona assert
en C y C++. La JVM tiene muy buenas herramientas de depuración, y combinadas con assert
y excepciones, puedes identificar fácilmente dónde algo salió mal (los rastreos de pila son mucho mejores que solo un número de línea).
Creo que la razón por la que Ruby y Perl tienen esas macros es porque fueron creadas por hackers de C. Nunca utilicé ninguno de esos lenguajes para conocer el nivel de soporte de depuración o qué tan útiles son realmente las macros.
Puedo confirmar que no se usan mucho. La forma normal de obtener información sobre un marco en Perl, ya sea dentro del depurador o fuera de él, es usar la función 'llamante' con un número de cuadro como argumento. 0 es donde estás ahora, 1 es tu interlocutor, 2 es * su * persona que llama, etc. Esto ahora devuelve el paquete, el nombre de archivo, la línea, la subrutina y un montón de otras cosas del marco. Por lo tanto, normalmente usaría la interfaz funcional para obtener esa información, no las antiguas pseudo-macros '__FILE__' y' __LINE__'. – tchrist
¿Por qué es tan lento? El equivalente en Perl (es decir, a través de 'calller') es muy rápido. – tchrist
Los rastros de pila de Java pueden ser bastante profundos, incluso más increíbles. El método [Throwable.fillInStackTrace] (http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#fillInStackTrace%28%29) solo lleva un tiempo para generar los datos de seguimiento de pila estructura. Visite http://stackoverflow.com/a/3980148/190201 para una mirada más profunda. Ciertamente no es demasiado lento de usar para la depuración, pero es bueno conocer su costo antes de usarlo. – ataylor