2009-01-27の読みさし

絶滅も進化も酸素濃度が決めた 恐竜はなぜ鳥に進化したのか:中断

面白いんだけど、いろいろあって中断。また今度読もう。

実践 Web Standards Design ~Web標準の基本とCSSレイアウト&Tips~:+:20%

実践 Web Standards Design ~Web標準の基本とCSSレイアウト&Tips~

実践 Web Standards Design ~Web標準の基本とCSSレイアウト&Tips~

面白い。丁寧に書かれてる。自分が作るサイトではこの本にしたがって作ってみようと思う。

Perl 5.8 で XML::Simple を使ったときに Pseudo-hashes are deprecated と怒られる問題の解決

XML::Simple がよろしくやってくれること

たとえば


 
 
 ...

とかなっている XML を、

my $obj = XMLin($xml);

とか

my $parser = new XML::Simple;
my $obj = $parser->XMLin($xml)

とか、した場合、次の $links は配列への参照になっている。

my $links = $obj->{entry}->{link}

つまり、$links->[0]->{rel} は「配列の最初の要素であるハッシュにおける、キーが "rel" の値」なので "self" であり、$links->[1]->{href} は「配列の 2 番目の要素であるハッシュにおける、キーが "href" の値」なので "a2.html" である。

一方で、同じコードで link がひとつしかない XML をパースさせると $links はハッシュへの参照になる。


 
 ...

の場合、"0.html" を得るためには $links->[0]->{rel} ではなく、$links->{rel} でアクセスしなければならない。早い話、「要素が一個しかない配列を作っても無駄じゃない。だったら配列を省いてあげるよ。」と XML::Simple がよろしくやってくれるわけだ。実際、取り出すコードも $links->[0]->{rel} から $links->{rel} へと短かくなっている。XML::Simple の本音としては、無駄を省いたとかそんなんじゃなく、「そもそも DTD もわかんないんじゃこうやるしかないでしょ」ということだろう。

link が一つかと思っていたら、二つのこともあるってとき

さて、WEB サービスを利用するなど、XML を通信でもらってきてそれを XML::Simple でパースしていたとしよう。WEB サービスが送ってくる XML は、先の XML 例の二つ目のように link が一個だけだったとしよう。なので、$links->{href} と書いて URL を得ることができる。

ところが、link は本来「一つ以上」含まれるもので、ごくまれに複数の link がついた XML が返されることが判明したとしよう。このままのコードだと配列である $links をハッシュのようにアクセスするからエラーになる、と思いきやそうではないらしい。それが Pseudo-hash。「あらかじめ使えるキーの値を限定したハッシュ」を表現するのに、無名ハッシュを無名配列で囲ったものが使える、という便利なもの。うん、便利なものなんだろう。
ということで、期せずして複数の link が入った XML が飛んでくると、期せずして Pseudo-hash を使ったことになってしまう。

Pseudo-hash は Perl 5.10 からは廃止になっているとのこと。ということは、Perl 5.8 だと「Pseudo-hash 使わないでね」と言われるだけのところが、Perl 5.10 以降だとエラーとなるということだろう(未確認)。

では、どう解決するの

たぶん、XML::Simple ではないパーサを使うのがいいでしょう。

というだけでは身もフタもないので、XML::Simple を使い続ける方法を。とりあえず、link がでてきたら、たとえ一個だけでも配列に入れて返してね、というお願いをしてあげるのが一つ。

my $parser = new XML::Simple(ForceArray => ['link']);
my $obj = $parser->XMLin($xml)

でもって、ちゃんと配列として扱ってあげる($links->[0]->{href}, $links[0]->{hreef} みたいに)。

そんな感じで。