日記

8月 12日 (土)

1. だらだら

雷うるさい。静かにしてくれ。

一日中だらだらとFF3(FC版)をやったり、だらだらとサークルチェックをしたり。NDS版のFF3は周囲の評判を見てからにしましょうかね。たまねぎ剣士が隠しジョブ扱いなのが妙に気になりますが。

それよりSVNサーバの再構築をさっさとやれよ、と。

8月 13日 (日)

1. C70

1.1. 戦地

有明まんが祭り三日目。今回は珍しく11時過ぎに現地に到着した(個人的にはこれでも早い方)ので、東から攻めてみました。まあ、目的はTRASHBOX#15と知人への挨拶だけですけどね。目的を達成した後は早々に西へ退却し、適当に物色したり、旅人さんと駄弁っていたり。いくつか予想外の収穫があったのと、音楽系が私のニーズとほとんどマッチせずに大ハズレだったのとで、戦績はまずまず、といったところでしょうか。

暑いのと荷物が重いのとで、私は二時半過ぎに一旦戦線を離脱しました。

1.2. 404 Maid Not Found.

離脱先がアキバなのが少々アレです。目的はただ一つ、THE メイド服と機関銃なんですが、量販店はどこも売り切れ。これは一体どうしたことか。そんなに売れているのか。某ファミ通や某巨大匿名掲示板での評価はいまいちだったのに。

そういえば、「ひぐらしナントカ」が目当てなのか、同人ショップ数店の前が人の列で埋まっていました。もちろん、本日の有明に比べれば大したことはありませんが、通行の邪魔ですねあの群れ。

1.3. 鍋

一旦帰宅し、シャワーを浴びてサッパリしてから再出撃。戦場から引き上げ途中の旅人さん達と上野で合流し、Hiroshi氏宅でまったり休憩してから、わたる氏も加わって鍋打ち上げへ。ごちそうさまでした。

ところで、Hiroshi氏宅には山のようにゲームと本が積まれており、その量はうちよりも遥かに多いはずなんですが、なぜか整然としています。うちは無造作に積まれているせいか、雑然としています。積み方にコツがあるんでしょうかね。

8月 14日 (月)

1. 停電

普通に出勤ですよ?

朝から電車が遅れていて、何事かと思えば大規模な停電だったようです。今回は落雷などの天災ではなく、どちらかと言えば人災に近い事故ですね。東京広域でと報じられていたので、うちのサーバは大丈夫かいなと心配になりましたが、Webサーバにアクセスできたので大丈夫 *1 と判断してひと安心。

  • *1: 自動起動ではないので、フリーズ、シャットダウン、リブートなどされると接続できなくなる。

2. 一撃必殺!エクセリオンバスターA.C.S!!

レイジングハート A.C.S.展開モード。所持者の顔が何か違うような気がするんですが、何だろう。白い服を着た「なのはさん」は、やることが何かと「黒い」ので、いっそ悪者顔にしてしまうというのも一興かと思います。

黒と言えば、先日買った黒セイバー、上半身を持ち上げると、毎回下半身とスカートがゴトっと落ちて「胴部絶交・黄泉送り」状態。パーツがしっかりはまらないんですよね。せめてスカートだけでも残れば「脚なんて飾りです!」と開き直れるんですが。

8月 17日 (木)

1. Subversion復旧メモ

Apache2とSubversionインストール完了。Apache2は枯れている2.0系にしました。

さて、リポジトリそのものはマウントするだけで使い回せるから良いものの、チェックアウト中の作業コピーは?チェックアウトした作業コピーを別のブランチに切り替えるには、svn switchを使います。当然URLも変わりますから、これを利用できないかと考えたわけですが、今回はスイッチ元のサーバがすでにいない(死亡した)ため、スイッチできません。ではどうしましょうか、という問題。

以前のSVNサーバのホスト名をoldserver 、新SVNサーバをnewserver とします。また、リポジトリのURLはそれぞれ http://oldserver/svn/hoge 、http://newserver/svn/hoge とします。まず、hostsを書き換えて、旧サーバ名を新サーバのIPアドレスに紐付けます。

192.168.1.1  newserver  oldserver

現在の作業コピーを(oldserverに対して)コミットします。ホスト名 oldserver のIPアドレスは新サーバと同じですから、正常にコミットできます。ちなみに、この状態でもスイッチはできません。なぜなら、スイッチ元とスイッチ先の実体が同じだからです。

コミットしたら、その作業コピーを破棄し、新たに newserver からチェックアウトします。これで作業コピーは新サーバと対応したことになりました。

とはいえ、あちこちにチェックアウトしている作業コピーについてこれをやるのは面倒ですね。

8月 18日 (金)

1. ActivePerlのPerlScriptで日本語

1.1. 概要と基礎知識

ActivePerlのPerlScriptで、ソースコード中に日本語文字を使用すると謎のエラーに悩まされるというのは、その筋では有名かもしれません。バージョン5.8系でuse utf8プラグマを使用し、ソースコードをUTF-8で符号化しても解決しません。要するに、マルチバイト文字に対応していないということでしょう。この辺の状況を調べてみました。

実証は次の条件下で行いました。

  • 改行コードはCRLF(0x0D 0x0A)
  • タブ文字(0x09)は使わない

まずはUS-ASCII。所謂「半角英数等」だけで書かれたソースコードです。

use utf8;
# UTF-8 encoded
MsgBox(&j0);

sub j0()
{
  return 'j0';
}

1;

このソースコードをcscriptコマンドで実行させると、期待通りの結果が得られます。つまり、j0 というメッセージ付きのダイアログが表示されます。しかし、次のソースコードを実行させると、妙な文法エラーが発生します。おそらく皆が指摘しているとおり、内部で文字数とオクテット数をごちゃ混ぜにして処理しているのが原因でしょう。なお、ソースコード中の改行の数や空白文字の数、コメントの内容等が僅かに違うだけで、エラーの内容は変化します。

use utf8;
# UTF-8で符号化したソースファイル
MsgBox(&j1);

sub j1()
{
  return 'j1';
}

1;
>cscript j1.pls
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

j1.pls(7, 0) PerlScript Error:
       (in cleanup) Can't find string terminator "'" anywhere before EOF

このバグが何年も放置されていることを考えると、ActiveStateが真面目に対応するのは期待できませんし、対応したところで現バージョンのActivePerlが動作しないことには変りありません。では、この問題をどうやって回避するか。アプローチとしては四つあります。

  1. マルチバイト文字を使わない
  2. ファイル全体の文字数 > スクリプト部分のオクテット数となるように詰め物をする
  3. 実行時に動的コンパイルする
  4. エラーにならないような符号化方法を探す

これらを一つずつ見ていきましょう。

1.2. マルチバイト文字を使わない

最も単純で、それでいて最も難しい解決方法です。確実な回避方法ではありますが、コメントに日本語文字を使いたいという要求は満たせません。もちろん、「ローマ字で書く」など論外です。

1.3. 詰め物をしてごまかす

ファイル全体の文字数 > スクリプト部分のオクテット数となるように、ファイル末尾に__DATA__などを書いて詰め物をすれば、回避できることがあるようです。ただし、確実ではありませんし、どれだけ詰めればよいのかがわかりづらいため、実用的とは言い難いでしょう。

1.4. 実行時に動的コンパイルする

下記のスクリプトを使用して、実行したいファイルを動的にコンパイルさせると期待通りに動作します。

use utf8;
require 'j1.pls';

useで静的に呼び出しても動作します。このやり方では、呼び出すファイルの拡張子をpmに変更する必要があります。

use utf8;
use lib qw(.);
use j1;

つまり、requireやuseで呼び出してやれば、期待通りに動作するということでしょう。静的か動的かは関係ないようです。

1.5. 符号化方法で回避

patch for PerlScript 5.8.7.813での解析結果を見ると、ActivePerl内部でwcslen(3)やWindows API WideCharToMultiByteの利用法を誤っていることがわかります。つまり、大方の予想通り、文字数とオクテット数をごっちゃにしている、と。では、日本語を扱える符号化方法の中で、wcslen(3)やWideCharToMultiByteを騙せる(US-ASCIIと思いこませる)ようなものはないでしょうか。US-ASCIIと思わせられれば、文字数とオクテット数が一致するので、期待通りに動作するはずです。そのような符号化方法が一つあります。ISO-2022-JPです。

#use utf8;
# ISO-2022-JPで符号化したソースファイル
MsgBox(&j2);

sub j2()
{
  return 'j2';
}

1;

このソースコード(もちろんISO-2022-JPで符号化した)をcscriptで実行すれば、期待通りの結果になります。ソースコードをおもむろにバイナリダンプしてみます。

0000000  23 75 73 65 20 75 74 66 38 3b 0d 0a 23 20 49 53
0000020  4f 2d 32 30 32 32 2d 4a 50 1b 24 42 24 47 49 64
0000040  39 66 32 3d 24 37 24 3f 25 3d 21 3c 25 39 25 55
0000060  25 21 25 24 25 6b 1b 28 42 0d 0a 70 72 69 6e 74
0000100  20 4d 73 67 42 6f 78 28 26 6a 32 29 3b 0d 0a 0d
0000120  0a 73 75 62 20 6a 32 28 29 0d 0a 7b 0d 0a 20 20
0000140  72 65 74 75 72 6e 20 27 6a 32 27 3b 0d 0a 7d 0d
0000160  0a 0d 0a 31 3b 0d 0a

日本語文字の部分だけピックアップしてみましょう。

1b 24 42 24 47 49 64 39 66 32 3d 24 37 24 3f 25 3d 21 3c 25 39 25 55 25 21 25 24 25 6b 1b 28 42
_$B$GId9f2=$7$?%=!<%9%U%!%$%k_(B

なるほど、これならごまかせそうですね。さすが7-bitエンコーディング。ただし、ISO-2022-JPで符号化すると、$や%といった、Perlにとって特別な意味を持つ文字が頻発するため、スクリプト中で使用する場合は細心の注意が必要になります。例えば、JIS X 0208-1983への切り替えである ESC $ B (1b 24 42)をqqなどで評価すると、これはPerlから見ればESCに続くスカラー変数$B として処理されてしまいます。このような意図しない結果を招かずに済ませるには、日本語文字はコメント以外には使用しないようにするのが良いでしょう。

なお、同じ7-bitエンコーディングであるUTF-7では対応できません。理由は面倒なので説明しません。文字コードの部屋 -- Unicode のエンコーディングを読んで考えてください。

1.6. 結論

現実解としては、次の二つに絞られるでしょう。

  • requireやuseで動的・静的コンパイルする
  • ISO-2022-JPで符号化する

…というかですね、ActivePerlがちゃんと対応していれば、こんなことせずに済むんだよ!

8月 19日 (土)

1. ActivePerlの〜を修正

昨日のActivePerlのPerlScriptで日本語のサンプル、printステートメントは要らないので削除しました。サンプルに余計なものがあるのは良くない。

2. Text-ACE メモ

近日公開できるといいな、な状態の、サクラエディタのマクロです。

例えば、Hoge.tjsというファイルを編集していたとします。拡張子がtjsなのですから、TJSのソースを書いているのだと推測できます(そのくらいは計算機でも可能)。ユーザが次の行を書いたとします。

function hoge foo bar

こう書いてあると、何となく「関数だね。関数名はhogeで、引数はfooとbarだ。そんな関数を実装したいのだろう。」と想像できますね。そこまでわかれば、あと書くことはだいたい決まってきます。大抵のプログラマは次のようなことを書くのではないでしょうか。

/***
関数の説明
@param foo 
@param bar 
@return
*/
function hoge(foo, bar)
{
	var rc = void;

	return rc;
}

今のところ、C/C++でもこのくらいならできます。テンプレート次第でどうにでも化けますけどね。

function, int, hoge, int argc, char *argv[], char* (*fp)()
/***
関数の説明を記述してください。
@param argc 
@param argv 
@param fp 
@return
*/
int hoge(int argc, char *argv[], char* (*fp)())
{
	int rc = /* 戻り値 */ ;

	return rc;
}

Eclipseなど大抵のIDE(統合開発環境)なら搭載されていそうな機能ですね…Eclipseはよく知りませんが *1 。というわけで、こういった定型処理を自動化させるマクロを作っています。いや、作るよりもドキュメントを書くのが大変で大変で、もう。

  • *1: 以前自宅PCにインストールしたことがありますが、起動が遅い、その他何かと重たい、何このヘヴィ級、アンインストール、で終了。