実行中のgroovyの行番号を知るためのもうひとつの方法 - でも、だめなようです。
2007/10/15
2007/10/15
groovy
java
以前、Hさんに実行中のjavaの行番号を知る方法を教えていただきました。
下記のような感じです。
new Throwable().getStackTrace()[0].getLineNumber()
Java言語のすべてのエラーと例外のスーパークラスになるThrowableを利用しています。
さて、groovyで同じようしようとすると、ちょっと工夫しないといけないようです。
まずためしに例外を発生させて行の情報をみてみます。
println "i am test script"
new RuntimeException("i am test script").printStackTrace()
new RuntimeException("i am test script").printStackTrace()
を実行してみますと。
java.lang.RuntimeException: i am test script
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.codehaus.groovy.runtime.MetaClassHelper.doConstructorInvoke(MetaClassHelper.java:562)
at groovy.lang.MetaClassImpl.doConstructorInvoke(MetaClassImpl.java:1756)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:758)
at groovy.lang.MetaClassImpl.invokeConstructor(MetaClassImpl.java:688)
at org.codehaus.groovy.runtime.Invoker.invokeConstructorOf(Invoker.java:163)
at org.codehaus.groovy.runtime.InvokerHelper.invokeConstructorOf(InvokerHelper.java:140)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeNewN(ScriptBytecodeAdapter.java:243)
at t_linenumber.run(t_linenumber.groovy:3)
at gjdk.t_linenumber_GroovyReflector.invoke(Unknown Source)
at groovy.lang.MetaMethod.invoke(MetaMethod.java:115)
at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:713)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:560)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:450)
at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:131)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:111)
at org.codehaus.groovy.runtime.InvokerHelper.runScript(InvokerHelper.java:408)
at gjdk.org.codehaus.groovy.runtime.InvokerHelper_GroovyReflector.invoke(Unknown Source)
at groovy.lang.MetaMethod.invoke(MetaMethod.java:115)
at org.codehaus.groovy.runtime.MetaClassHelper.doMethodInvoke(MetaClassHelper.java:713)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:664)
at org.codehaus.groovy.runtime.Invoker.invokeMethod(Invoker.java:111)
at org.codehaus.groovy.runtime.InvokerHelper.invokeMethod(InvokerHelper.java:111)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.invokeMethodN(ScriptBytecodeAdapter.java:187)
at t_linenumber.main(t_linenumber.groovy)
真ん中あたりの出力で、3行目でランタイムエラーを発生させているのがわかります。
この部分を抜き出してみればいいような感じです。
それで、できあがったコードは下記のような感じ。
new Throwable().getStackTrace().each{ s ->
matcher = s =~ /run\(.*\:([0-9]+)/
if(matcher.find()) println "line number: ${matcher.group(1)}"
}
matcher = s =~ /run\(.*\:([0-9]+)/
if(matcher.find()) println "line number: ${matcher.group(1)}"
}
とても楽観的なコードです。
なんとなくうまくいっているようにはみえます。
クロージャ使ってます。
動作させて、ためした環境は、eclipse + groovy pluginです。
動作の仕方によってはまったく役にたたないようです...Orz
プログラマメモ2: 実行中のgroovyの行番号を知るためのもうひとつの方法 - これだといいかも。
: