CGI.pm のアップロード機能

ただいま perl で画像アップロード機能を作成中でして。んで、ベタに CGI.pm でサクっと実装したら、何かアップロードしたファイルがぶっ壊れるじゃないですか。何故。

#!/usr/local/bin/perl -l


use CGI; my $q = new CGI; my $uploadfile = $q->upload('photo');

$path = "./image/photo.jpg"; open (OUT, ">$path"); binmode OUT; print OUT while (<$uploadfile>); close (OUT); close ($uploadfile) if ($CGI::OS ne 'UNIX'); chmod (0666, $path);

exit;

実際には mime によって拡張子を判定したりしなくちゃいけないんだけど、大体こんな感じ。もうね、どこが悪いのかサッパリ分からないわけですよ。

で、イジり倒していたら、原因は "-l" オプション。コイツを消したら、キレイに動きましたよ。って、マジでかあ。バイナリデータの途中で勝手に chomp したりしちゃって、おかしくなっていたんだよね。言われれば、分かる。分かるんだけどさ…ううう。

正規表現やらリファレンス渡しやらで、何回かハマって時間を無為にしてきたけど、これは本当にハマりまくった。まあ、良い勉強になりましたです。ハイ。

配列の引数渡し

納得いかねえ。

いま久しぶりに perl を書いていまして。で、サブルーチンの引数にスカラ変数と配列を渡したら、何か微妙な動作するわけですよ。配列のN番目がおかしい。

$hoge = "xxx";
@arr = qw(abc ABC 123);
sub func {
    local ( @a, $b ) = @_;
    print($#a);    # $#a は配列の最後の添え字の参照
}
&func(@arr, $hoge);

気持ちとしてはね、「2」になって欲しかったわけ。でも、現実は「3」とか言っちゃって、手厳しい。アレか、俺が田舎者だからってバカにしてんのか。それともアレか、俺が毛沢東を「マオツォートン」って呼ぶからか。ううう。

動きとしては、$b に入って欲しい値まで @a に吸収されてるってことだよね。そりゃ分かるけどさ、なんか優しくないじゃないか。お前みたいなヤツにはな、typeglob型使ってやるかんな!

$hoge = "xxx";
@arr = qw(abc ABC 123);
sub func {
    local ( *a, *b ) = @_;
    print($#a);    # $#a は配列の要素数の参照
}
&func(*arr, *hoge);

というわけで、typeglob型(構造体みたいなやつ)を使って一件落着。しかし納得いかない。perl は何でもできて面白いんだけど、こういう挙動の怪しいとこが、ちょっとクセありすぎて困る。まあ、そんなこと言ってるなら typeglob になんか逃げないで、OOP手法でちゃんとリファレンス使うようなことしろって話ですか。んー、力量不足だ。