ちゃんとエラークラス吐くバージョンがリリース。kiyoya さんのパッチ。
ruby extconf.rb --enable-error-handler して Makefile 作成。ちゃんと exslt もリンクさせるため、OBJS に /lib/libxml2.dll.a /lib/libexslt.dll.a /lib/libxslt.dll.a
を追加。なんか知らんけど明示的に指定しないとリンクされなくて ld が怒る@cygwin (このバージョンに限らず)
XML::XSLT::XSLTError と、そのサブクラス XML::XSLT::ParsingError, XML::XSLT::TransformationError が追加される。変換用 XML ファイルのエラーなのか、XSLT ファイルのエラーなのかはわからなく。そのかわりエラー発生のタイミングが変わった。serve
時ではなく、xml=
のときに出るようになった。だから問題ない。
エラーの message
の意味がないっぽいので、--enable-error-handler 時には rb_raise 第2引数を STR2CSTR(rb_ary_to_s(rb_cvar_get(cXSLT, rb_intern("@@errors"))))
とかにしたほうがいい感じ。--enable-error-handler は errors が定義されるのがキモイけど俺はそんなに気にならない。
第二引数を変えるだけだと以下のコードがダメ。
xslt = XML::XSLT.new() xslt2 = XML::XSLT.new() begin xslt.xml = File.read("examples/fuzface.xml") xslt.xsl = File.read("examples/fuzface.xsl") out = xslt.serve() print out; rescue XML::XSLT::XSLTError => e p XML::XSLT.class_eval("@@errors") #=> (1) p e.message #=> (2) end p XML::XSLT.class_eval("@@errors") #=> (3) begin xslt2.xml = File.read("examples/fuzface.xml") xslt2.xsl = File.read("examples/fuzface.xsl") out = xslt2.serve() print out; rescue XML::XSLT::XSLTError => e p e.message #=> (4) end
(3) で (2) のときと同じ (4) のとき前のエラーメッセージが紛れ込む。クラス変数使ってるからだろうけど、単純にインスタンス変数にしないのにはなんか理由があるんだろうからとりあえずそのままにして、
void xslt_raise(VALUE cError) { #ifdef USE_ERROR_HANDLER VALUE errors = rb_cvar_get(cXSLT, rb_intern("@@errors")); VALUE error_str = rb_ary_to_s(errors); rb_ary_clear(errors); rb_raise(cError, STR2CSTR(error_str)); return; #endif rb_raise(cError, ""); }
とか作って経由させ、リセットさせてみる。XML::XSLT.errors
は常に空の配列が返るようになって無意味になる。
ruby-xslt.0.9.1.error_message.patch
スレッドの切り替えってどういうタイミングなんだろう。