Arkの依存モジュールの一つでもあるText::SimpleTableですが、2009/07/03のバージョン1.2で、「列幅を1バイトと指定した列で1バイトを超える列名や値が入るときに無限ループする」という不具合が解消しました。
このモジュールは、列幅を超える列名や値について、-(ハイフン)で区切って次の行を描画するという仕組みです。当初のバージョンでは、列幅が1バイトだと(-それ自体で1バイトを専有してしまうので)、無限に次の行を描画するという不具合が生じていました。
この解決策として、私のオレオレパッチでは「列幅が1なのに列名や値が1を超える場合にはcroakする」という場当たり的な方法を採ったのですが、本家1.2では「列幅が1だろうが何だろうが最小の列幅を2にする」という対応になっています。
Arkの依存モジュールということで知ったモジュールですが、CLIでは結構便利なモジュールで、私もMyApp::CLI::Viewで色々と使わせていただいています。今回の改定で、全列幅がいっぱいにならないように気をつけようと思います。
一応、何を言っているかというコードを以下に掲げておきます。
Amikeco::CLI::Controller::Raceの例
CLIだとWebと違ってViewとControllerを峻別していないのですが、将来的にはちゃんと分けようと思います。などと書いている間に直せよ、といったところですが......。
ともあれ、Text::SimpleTableの無限ループ(修正済み)の実例です。
sub all_races {
my $self = shift;
my $logic = Amikeco::Logic::Race->new;
my $encoding = find_encoding('cp932');
my $table = Text::SimpleTable->new(
[ 1, 'i' ], # 'id'とすると、Text::SimpleTable 1.2より前で無限ループ
[ 3, 'en' ],
[ 5, 'ja' ],
[12, 'name_en'],
[15, 'name_ja'],
[12, 'name_de'],
[12, 'name_fr'],
);
foreach my $columns (@{ $logic->all_races }) {
$table->row(
$columns->id,
(
map {
$encoding->encode($columns->$_); # まとめてencodeすると破綻
} qw(
abbreviation_en abbreviation_ja
name_en name_ja name_de name_fr
)
),
);
}
print $table->draw;
return;
}
上記は、プレイヤーキャラクターの種族を保存したテーブルから、種族の一覧を出す処理です。$columns->idとして種族IDを持ってくる列では、IDなんだからidと記述したいところです。
ところが列幅を1としているので、idという2バイト分の文字列を1バイトに収めようとして、iとdをハイフン-で繋げようとしてくれるのですが、i-という値自体が2バイトになっているので、さらにこれにハイフンを付けて......というような無限ループが生じていたという案配です。
1.2では、これが必ず2バイト確保されるので、無限ループは起きなくなります。
上記のような場合、例えばIDが1バイトで絶対に足りる場合(種族は5つと想定していますので、0から4ですね)でも2バイトが確保されるので、意図して1バイトにすることが出来なくなったと、つまりそういうことです。
折角2バイトをもらえるので、この場合素直にidという列名を付けるのが良いかと思ったり。
コメントする