perlで書いたメールフォームから送信したメールの件名(日本語)が、Thunderbirdでだけ文字化けする。
結論から言うと、件名のエンコード処理が抜けていたので文字化けしていた。Outlookなどは、空気を読んで勝手に文字コード判別をしてくれていたので、適切な表示がなされていたようだ。えー、要するに Thunderbird は KY ってことで。
悪態ついてないで、ソース修正。
# 修正前 my $subject = MIME::Base64::encode($mailsubject, ""); chomp $subject; $subject = "=?ISO-2022-JP?B?$subject?=";
Base64でエンコードする前に、入力文字列($mailsubject)を、ISO-2022-JP(JIS)に変換してあげる必要がある。
# 修正後 $mailsubject = Jcode::convert($mailsubject, 'jis'); my $subject = MIME::Base64::encode($mailsubject, ""); chomp $subject; $subject = "=?ISO-2022-JP?B?$subject?=";
これでメールクライアントによらず文字化けせずメール送信できるようになった。これって、すごい基本的な処理フローだと思うのだけど、今まで知らずに生きてきた。恥ずかしい。すみません。生れて、すみません。二十一世紀旗手ですよ。
Posted by dT by 23:36 | Comments (0) | TrackBacks (0)
perlで書いたメールフォームで、件名をめっちゃ長くしてみたら文字化けした。
my $subject = MIME::Base64::encode($mailsubject); chomp $subject; $subject = "=?ISO-2022-JP?B?$subject?=";
なんじゃろうと思って調べてみると、原因はMIME::Base64のエンコード処理だった。たぶん基本的なことだと思うのだけど、今まで支障がなくて気付かなかった。ううう。
encode_base64関数は、以下のような動きをするのが仕様。
返されるエンコードされた文字列は76文字を越えないように分割され、空文字列でなければ$eolが最後に付きます。もしエンコードされた文字列を複数の行に分割したくない場合は、2番目の引数として空白の文字列を渡してください。
要は、長い件名にしちゃうと勝手に改行コード入れちゃうから文字化けするって話。改行されたくなかったら、第2引数に空文字を指定しましょう、と。引数2つ取れることなんて、知らなんだ。無知は怖い。まんじゅう怖い。お茶も怖い。
ということで、以下のようにしてアッサリ解決。
my $subject = MIME::Base64::encode($mailsubject, "");
ちゃんとドキュメント読まないとダメってことですな。
Posted by dT by 12:27 | Comments (0) | TrackBacks (0)
Perlさん曰く、「Unrecognized character \xE3」である。
一瞥すると何のことか分からないのだけど、要するにクォーテーションの関係性が崩壊していて、プログラムが理解できないということ。最も単純な話では、クォーテーションの閉じ忘れがある。
今回はテンプレートエンジンを噛ませていて、テンプレートタグを展開したリテラルに、クォーテーションが含まれていたため、関係性が崩壊していた。「'」を「'」に置換してから取扱うように変更すれば良いんだけど、表示側のソースをいじりたくなくて、DBへのINSERT処理側を改造。ホントはダメなんだけど、HTML表示にしか使わないデータだから良しとする。
怠慢って素晴らしいという話。
Posted by dT by 05:04 | Comments (0) | TrackBacks (0)
sendmail 君ってば、未改行の長文をメールしようとすると、勝手に改行コードを挿入してくれちゃうのね。知らなかった。うちの環境だと、986バイトを超えると強制改行コード。優しい仕様だとは思うんだけど、2バイト文字を分断してでも改行コード入れる一途さに、ちょっと辟易。
どうしようもないので、sendmail に文字列を渡す前に、自前で長すぎるテキストを改行するように変更。もちろんマルチバイト対応で。
Posted by dT by 18:08 | Comments (0) | TrackBacks (0)
CPAN から何かをインストールしようとするたびに、いつも方法を忘れているので、メモ。
# perl -MCPAN -e shell cpan> install モジュール名 [インストール] cpan> quit
FTP がうまくいかずにインストールが止まってしまったりすることも。そういうときは、ソースからインストールすべし。個人的には、ソースからの方が意味が分かってスッキリする。所詮は古い人間だもの。
# perl Makefile.PL # make # make test # make install
しかし、そもそも今どんなモジュールを組込んでいるのか忘れていて、本当に追加すべきかどうかが分からない。あれ、このモジュールって入っているんだっけか。二歩進んで三歩下がるこのブログ。
「使用可能なモジュールの一覧取得」
「Perlモジュールの確認」
この辺を見て解決。@INC を使えば良いのか、なるほど。ちなみに、今から入れようと思っていたモジュールは全て組込み済みでしたよ。ムダ足ご苦労さん。ううう。
Posted by dT by 21:38 | Comments (1) | TrackBacks (0)
SWF::Builder を使えば、CGI を通して動的に Flash を生成することができるわけですよ。こりゃあ面白いと思って、しばし使いどころを考えていたんだけど、別に Flash 内部に吸収すればできるんじゃないのって話ばかり。間に perl を挟む利点が、思いつかないなあ。
他の人はどんな使い方してんだろうと思って検索したら、フォント周辺で上手いことやろうってことで盛り上がってるっぽい。とりあえず、generative.info さんとこの「SWF::BuilderでLinuxサーバー上でフォント生成は可能か」という熱いエントリーを追いつつ、自分でもベンジャミンの名言で挑戦。うん、できた。素敵!
でもでも、単にサーバサイドで入力文字列をフォント化するのであれば、SWF::Builder じゃなくてもイケるよなあ、と。もっと、サーバが動的に swf ファイルを生成することの意味があるような使い方って、無いんだろうか。
パラメータに合わせて動きが変わるような Flash ならば、それは Flash 内部でそういう風に作りこめば良い。SWF::Builder の効用を考えるなら、入力内容を swf 生成時に埋め込まないといけないようなもの…。うーん。
Flash が Flash を作って読み込んで、その Flash がまた Flash を作って…みたいなこととかしたら、意味ないけど面白かったりするのかなあ。あー、データ収納箱として swf ファイルを使ったりするか。サウンドも使えるっぽいし、そこに全部詰め込むとかね。苦しいか。
とりあえず、ちょっと寝かせておこうっと。
Posted by dT by 19:25 | Comments (0) | TrackBacks (0)
前回インストールした SWF::Builder を使って実際に flash を作成してみた。率直な感想として、かなり面白い。今回は静的にコードを書いて描画したんだけど、CGI を絡めて動的に描画することも可能なわけで。アイデア次第でいかようにも拡がりそう。素敵だ。
ちなみに、このチンケなムービー、ずっと見てると酔いそうになる。申し訳ない。
とりあえず、例によってソースさらしておきまふ。
Posted by dT by 23:12 | Comments (0) | TrackBacks (0)
CPAN をうろついていたら、SWF::Builder という面白げなモジュールを発見。perl で flash が作れるなんて、かなり素敵なことが起こりそうじゃないですか。
というわけで、以下インストールのメモ。
Posted by dT by 22:58 | Comments (0) | TrackBacks (0)
MVC モデルに慣れ親しんだせいで、画面とロジックを共存させる旧来の perl のやり方が、スゲーうさん臭く思えていた。それだけに HTML::Template モジュールとの出会いは衝撃的。もう、これ無しで perl を使ったWebアプリなんざ作れないっすよ、お兄さん!
そんな愛しの HTML::Template モジュールのなかでも、とりわけ重宝しているのが、loop_context_vars オプション。jsp とか velocity だと、計算のロジック入れないといけない二段組が、スゲー簡単に実現できたりする。かゆいところに手が届いていて良い感じ。素敵です。
以下、サンプルソース。
Posted by dT by 21:44 | Comments (0) | TrackBacks (0)
ただいま 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 したりしちゃって、おかしくなっていたんだよね。言われれば、分かる。分かるんだけどさ…ううう。
正規表現やらリファレンス渡しやらで、何回かハマって時間を無為にしてきたけど、これは本当にハマりまくった。まあ、良い勉強になりましたです。ハイ。
Posted by dT by 21:40 | Comments (0) | TrackBacks (0)
納得いかねえ。
いま久しぶりに 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手法でちゃんとリファレンス使うようなことしろって話ですか。んー、力量不足だ。
Posted by dT by 06:26 | Comments (0) | TrackBacks (0)