実行中のgroovyの行番号を知るためのもうひとつの方法 - でも、だめなようです。 2007/10/15
2007/10/15

以前、Hさんに実行中のjavaの行番号を知る方法を教えていただきました。
下記のような感じです。


new Throwable().getStackTrace()[0].getLineNumber()


Java言語のすべてのエラーと例外のスーパークラスになるThrowableを利用しています。

さて、groovyで同じようしようとすると、ちょっと工夫しないといけないようです。

まずためしに例外を発生させて行の情報をみてみます。

println "i am test script"

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)}"
}


とても楽観的なコードです。
なんとなくうまくいっているようにはみえます。
クロージャ使ってます。

動作させて、ためした環境は、eclipse + groovy pluginです。

動作の仕方によってはまったく役にたたないようです...Orz

プログラマメモ2: 実行中のgroovyの行番号を知るためのもうひとつの方法 - これだといいかも。

: