È possibile ottenere il numero di linea corrente tramite __LINE__
in Ruby o Perl. Per esempio:__LINE__ funzionalità in Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
C'è la stessa caratteristica in Groovy?
È possibile ottenere il numero di linea corrente tramite __LINE__
in Ruby o Perl. Per esempio:__LINE__ funzionalità in Groovy
print "filename: #{__FILE__}, line: #{__LINE__}"
C'è la stessa caratteristica in Groovy?
Non direttamente, ma è possibile ottenerlo attraverso una traccia di stack Exception (o Throwable). Per esempio:
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 parola di cautela però: ricevendo il numero di riga, il nome del file, o un metodo come questo è molto lento.
Non sono un esperto di Groovy, ma non penso. So che Java e C# non ce l'hanno.
La funzionalità __LINE__
ha veramente iniziato ad aiutare con il debug in C. C non ha eccezioni o molte altre caratteristiche dei linguaggi moderni, ma aveva macro che il compilatore poteva espandere ovunque nel codice, ecco perché avevamo bisogno di __FILE__
, __LINE__
, ecc. per farci sapere dove eravamo quando accadeva qualcosa di brutto. Questo è il modo in cui assert
funziona in C e C++. La JVM ha strumenti di debug molto buoni, e combinata con assert
ed eccezioni, puoi facilmente individuare dove qualcosa è andato storto (le tracce dello stack sono comunque migliori di un semplice numero di linea).
Credo che il motivo per cui Ruby e Perl hanno quei macro è perché sono stati creati dagli hacker C. Non ho mai usato nessuno di quei linguaggi per conoscere il livello di supporto per il debug o quanto sono davvero utili i macro.
Posso confermare che non sono molto utilizzati. Il modo normale per ottenere informazioni su un frame in Perl, sia all'interno del debugger che al di fuori di esso, è usare la funzione 'caller' con un numero di frame come argomento. 0 è dove sei adesso, 1 è il tuo chiamante, 2 è * il suo * chiamante, ecc. Questo ora restituisce il pacchetto del frame, il nome del file, la riga, la subroutine e un mucchio di altre cose. Quindi normalmente utilizzerai l'interfaccia funzionale per ottenere quelle informazioni, non i vecchi pseudo-machi '__FILE__' e' __LINE__'. – tchrist
Perché è così lento? L'equivalente in Perl (che significa 'caller') è molto veloce. – tchrist
Le tracce dello stack Java possono essere abbastanza profonde, ancora più groovy. Il metodo [Throwable.fillInStackTrace] (http://docs.oracle.com/javase/6/docs/api/java/lang/Throwable.html#fillInStackTrace%28%29) richiede solo un po 'di tempo per creare i dati di traccia dello stack struttura. Controlla http://stackoverflow.com/a/3980148/190201 per un look più approfondito. Non è certamente troppo lento da usare per il debug, ma è bene essere consapevoli dei suoi costi prima di usarlo. – ataylor