[Perl] Perl 5.8.5での日本語の扱い

勉強がてら小物スクリプトを書こうと思ったら文字コードではまってしまいました。
UTF-8のソースの中でShift-jisのHTMLを読み込んでテンプレートに従って出力。

Perl初心者が書いたほぼ初めて(Hello Worldを除く)のコードです。信用しないでください。

#!/usr/bin/perl -w
use strict;
use HTML::TreeBuilder;
use Template;
use utf8;

my $inputFile    = 'sample.html'; # shift-jis
my $templateFile = "template.html";
my $buff;

# ファイルをバッファに読み込み もっと簡単に書ける?
# LWP::Simpleで取得するように変更しよう
{
    my $handle;
    #    open($handle, "<:utf8", $inputFile) || die("file open error $!");
    open($handle, "<:encoding(shift-jis)", $inputFile) || die("file open error $!");
    read($handle, $buff, -s $inputFile);
    close($handle);
}

# TreeBuilder便利だな(正規表現と比べて遅そうだけど)
my $tree = HTML::TreeBuilder->new;
$tree->parse($buff);

# 解析するhtmlの構造に依存
my @tables = $tree->find_by_tag_name("table");
my @trs    = $tables[3]->find_by_tag_name("tr");
my @all    = ();

foreach my $tr (@trs) {

    my @tds = $tr->find_by_tag_name("td");
    my @ths = $tr->find_by_tag_name("th");

    next if !@tds;

    my %data = ();

    $data{rank}      = $ths[0] ? $ths[0]->as_text : "";
    $data{title}     = $tds[0] ? $tds[0]->as_text : "";
    $data{author}    = $tds[1] ? $tds[1]->as_text : "";
    $data{publisher} = $tds[2] ? $tds[2]->as_text : "";
    $data{count}     = $tds[3] ? $tds[3]->as_text : "";

    $data{author} =~ s/(‖|//).*//g;

    push(@all, {%data});
}

# rankでソート
@all = sort {$a->{rank} <=> $b->{rank} } @all;

# テンプレートとか使ってみる
my $output;
my $template = Template->new();
$template->process($templateFile, { all => \@all }, \$output) || die "Template process failed: ", $template->error(), "\n";

print $output

CとかJavaでテンプレートの解析コードを書いたことがありますがHTML::TreeBuilderとかTemplate Toolkitとか便利ですなぁ。
Perlの文法でまだあいまいなところはたくさんある。使いながら覚えるだろうか。

  • 怪しいところ
    • $hoge{hige} と $hoge->{hige}の違い
    • 参照渡しとか、代入時のコピーの挙動
    • {}