2009-01-27の読みさし
絶滅も進化も酸素濃度が決めた 恐竜はなぜ鳥に進化したのか:中断
面白いんだけど、いろいろあって中断。また今度読もう。
実践 Web Standards Design ~Web標準の基本とCSSレイアウト&Tips~:+:20%
実践 Web Standards Design ~Web標準の基本とCSSレイアウト&Tips~
- 作者: 市瀬裕哉,福島英児,望月真琴
- 出版社/メーカー: 技術評論社
- 発売日: 2008/11/29
- メディア: 大型本
- 購入: 18人 クリック: 293回
- この商品を含むブログ (60件) を見る
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} みたいに)。
そんな感じで。