Home > Perl > XML::Simple は遅い説における意外な落とし穴 - おまけ編

XML::Simple は遅い説における意外な落とし穴 - おまけ編

  • 2005-11-29 (火)
  • Perl
  • このエントリーを含むはてなブックマーク

前回の記事に引き続き、XML::Simple モジュールとその背後で利用されるパーサーにおける、ややおまけ的な内容について記述してみました。

目次:

  1. 背後で利用している XML::SAXパーサーの確実な確認方法
  2. $/ 変数の状態によって利用パーサーが変わる妙について

背後で利用している XML::SAXパーサーの確実な確認方法

基本的な確認方法は前回記事にて記述しましたが、より確実に、コード実行時に利用しているパーサーが何なのかを確かめたい場合は、ちと泥臭いですが、以下のように XML::Simple のソースコードに直接追記する事で確認できます。

XML::Simple (Simple.pm) の build_tree 関数の以下の箇所(v2.14ならば281-283行目)に

  $XML::SAX::ParserPackage = $preferred_parser if($preferred_parser);

my $sp = XML::SAX::ParserFactory->parser(Handler => $self);

こんな感じに一行 warn 文を追加:

  $XML::SAX::ParserPackage = $preferred_parser if($preferred_parser);

my $sp = XML::SAX::ParserFactory->parser(Handler => $self); warn $sp."\n"; # 追記箇所

これで XML::Simple 実行の際に use warnings を宣言しておけば、

XML::SAX::PurePerl=HASH(0x83a39e4)

のような文字列がSTDERRに出力されるようになります(微妙^^;)。

▲RETURN TO TOP

$/ 変数の状態によって利用パーサーが変わる妙について

上記の「背後で利用している XML::SAXパーサーの確実な確認方法」を用いて XML::Simple 実行時に裏で利用されているパーサーが何なのかを確実に判別できる状態にして、さらに XML::LibXML 等オプショナルなSAXパーサーが追加インストールされている状態にした上で、以下のようなコードを実行します:

why.pl

#!/usr/bin/perl
use strict;
use warnings;
use encoding 'utf8';
use XML::Simple;
die "Usage: ./why.pl xmlfile\n" if(!@ARGV);
my $xml;
{
open(IN,$ARGV[0]) or die;
local $/ = undef;
$xml = <IN>;
close(IN);
}
my $p = XML::Simple->new();
my $r = $p->XMLin($xml) or die;

以下適当なXMLデータを用いての実行結果:

$ ./why.pl sampleSmall.xml
XML::LibXML::SAX=HASH(0x82ccfdc)

最後にインストールしたSAXパーサー = XML::LibXML::SAX が利用されていることがわかります。では次に why.pl のファイルオープン処理を囲っているブロック記述を省いてみます。

why.pl (修正後)

#!/usr/bin/perl
use strict;
use warnings;
use encoding 'utf8';
use XML::Simple;
die "Usage: ./why.pl xmlfile\n" if(!@ARGV);
my $xml;
open(IN,$ARGV[0]) or die;
local $/ = undef;
$xml = <IN>;
close(IN);
my $p = XML::Simple->new();
my $r = $p->XMLin($xml) or die;

これを実行してみると...

$ ./why.pl sampleSmall.xml
XML::SAX::PurePerl=HASH(0x82cce00)

あら不思議。ファイルオープン処理、特に local $/=undef; 部分をブロック枠からはずした事で、暗黙的に利用されるSAXパーサーが変わってしまいました。

XML::Simple のソースコードを追ってみると、XMLin メソッド実行時にて(v2.14の場合 273行目)、

eval { require XML::SAX; };

なんてやっていたりしますので、先の local $/=undef 記述が XML::SAX のスコープ内でも有効になり、その結果なんらかの影響を与えているように見えます。結果、どうして利用するSAXパーサーが変化するかまでは追いませんでしたが(面倒くさくなった^^;)、

$/ 変数に対する操作は、きちんと {} ブロックで囲まないと、XML::Simple の暗黙的なパーサーの選択に影響を与えるので注意すべし

という事は言えるかと思われます。「妙」というよりかは、きちんとしたソースコードを書けなかったオマエがヘッポコってだけの事ですが(汗)。皆様ご注意くださいませ。

▲RETURN TO TOP

Comments:0

Comment Form

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

Remember personal info

Home > Perl > XML::Simple は遅い説における意外な落とし穴 - おまけ編

Search
Feeds

Page Top