Sunday, March 16, 2008

ActivePerl のドキュメントが不完全なときの対処方法

ActivePerl のインストール時に POD や HTML ファイルの生成が中途半端になる問題。

ActivePerl 5.10をLeopardにインストール

PerlはLeopardについてくるから(5.8だけど)それを使えばいいと思っていた。ところが、意外なところでひっかかった。

% perldoc perldoc
No documentation found for "perldoc".
% perldoc perlre
No documentation found for "perlre".
% which perldoc
/usr/bin/perldoc
%

えー。

「Mac OS X の ActivePerl でも同じ現象が出るの?」と早とちりしたけど、どうやら別の話。

ぼくの使っている Windows の ActivePerl は、最近のバージョンではインストール直後からドキュメントがまともに読めなかったりすることがあって、それが困ったちゃんだなぁという話。

不特定の perldoc が読めなかったり、ブラウザで読む User Guide から Core Documentation がごっそり抜け落ちてたりという現象が起きるんです。なんとなくしか覚えていないのですが、ぼくのところでは、この問題は ActivePerl 5.8.8 build 820 で発生しはじめたと思います。なんだか根が深そうに見えるのできちんとは調べられず、以下のようなひどいやりかたで対処しています。

ActivePerl::DocTools::Pod モジュールは、Windows の場合 <ActivePerl のインストールディレクトリ>\lib\ActivePerl\DocTools\Pod.pm です。

$ diff -u Pod.pm~ Pod.pm
--- Pod.pm~     2006-12-06 11:55:20.000000000 +0900
+++ Pod.pm      2008-01-20 20:44:05.415842100 +0900
@@ -144,7 +144,9 @@
     }
     close (TMPFILE) || die "Couldn't write all of $outfile.tmp: $!";
     close (HTMLFILE);
-    unlink($outfile); # bug 61127
+    unlink($outfile) # bug 61127
+      or die "Couldn't unlink $outfile: $!";
+    sleep 0 while (-e $outfile);
     rename("$outfile.tmp", $outfile) || die "Couldn't rename $outfile.tmp back to $outfile: $!";
 }

このあと以下のコマンドを実行すればどのドキュメントも読めるようになるかと思います。

# ap-update-html --force

以下、中途半端な考察。

ActivePerl のインストールプロセスには、User Guide などの HTML ファイルをまとめて生成する処理がある。ここで使われている ActivePerl::DocTools::Pod モジュールの pod2html がうまく処理できずに死んでしまうと、POD ファイルと HTML ドキュメントの生成が中途半端な状態になります。
同様の処理は PPM を使ってモジュールをインストールしたときにも実行されます。

ActivePerl と一緒にインストールされる ap-update-html を実行すると、ActivePerl の基本的な POD ファイルとすべてのモジュールの HTML ドキュメントが生成・更新されます。

> ap-update-html --force --verbose

この修正を加えない場合、なにかの不運なタイミングで unlink したファイルがファイルシステム的にまだ(不完全な状態で?)残っていて rename に失敗することがあります。--force を付けずに繰り返し実行すればそのうち完走しますが。

> ap-update-html --force
Couldn't rename C:\Perl\html/lib/pods/perldos.html.tmp back to C:\Perl\html/lib/
pods/perldos.html: Permission denied at C:/Perl/lib/ActivePerl/DocTools/Pod.pm l
ine 148.

ぼくが調べたときには、どのファイルを処理している時に止まるのかは不定でした。rename できずに die した場合でも、人間の反応速度で確認した限りでは $outfile は既に消えてなくなっていたので、じゃあ消えるまで待ってあげればいいのかなぁという単純な対策です。

この問題が発生するのは OS やそのファイルシステム、はたまた時の運や日頃の行ないに依存するのかも知れません。

Bug #61127 Summary: Table of contents incomplete, non-ap links missing

Pod.pm のコメントからも分かるとおり ActiveState は Bug #61127 を認識しているものの、再現はできないそうで。ぼくの使う Windows + NTFS では 5割に迫る高確率で再現するんですけどね。;-)

でも、これは unlink の仕様を踏んじゃった ActiveState の作りのマズさなんじゃないかと思います。
このケースにあてはまるかは知りませんが、プログラミング Perl 第3版日本語版によれば、unlink が返ってきたからといって必ずしもファイルが削除済みであるわけではないように読みとれますし(unlink の項の脚註)。

 

追記@Sat Sep 06 13:46:08 2008

u-ch: ActivePerl 5.10.0 Build 1004 released

No comments:

Post a Comment