AI に Perl スクリプトを直してもらう

旧サイトで cron でずっと動かしていたスクリプトが、サーバーのOS入れ替えで動かなくなった。

更新履歴を見たら2001年に書いたものらしい。ふふ。24年間も黙々と動作していたとは。いにしへの jcode.pl を文字コード変換に使っていて、この部分でエラーが出ている。

jcode.pl を入れてもいいが、さすがに時代遅れなので書き換えようと決意。今どきは Encode モジュールを使うものらしい。というか、今どきはもう Perl じゃなく Python とかなんだろう。

一応言語は変えないことにして、Claude に直しを依頼した。

俺:以下はウェブサイトの更新時国を取得するPerlのスクリプトです。jcode.pl を使わない形に書き直してください。

Cl: このスクリプトをjcode.plを使わない形に書き直します。現代のPerlではEncodeモジュールが標準的ですので、それを使用します。

元のスクリプトをjcode.plを使わない形に書き直しました。主な変更点は以下の通りです:

主な変更点

  1. jcode.plの削除: require "/home/taro/id/jcode.pl";を削除し、代わりに標準的なEncodeモジュールを使用
  2. 文字エンコーディング変換の修正:
    • &jcode'convert(*variable, 'jis');convert_to_jis(\$variable);
    • 新しいconvert_to_jis関数でISO-2022-JP(JIS)エンコーディングに変換
  3. 現代的なPerlの記法に更新:
    • use strict;use warnings; を追加
    • レキシカルファイルハンドルを使用
    • 変数を適切にmyで宣言
  4. 配列処理の修正: $[..$#array0..$#array に変更($[は非推奨)

動作について

スクリプトの機能は元のものと同じです:

  • ウェブサイトのLast-Modifiedヘッダーやフィードの更新時刻を取得
  • 更新時刻順にソートして表示
  • HTML形式でテーブル出力
  • タイムアウト処理やエラーハンドリング

この書き直しにより、jcode.plへの依存が無くなり、現代的なPerlの標準モジュールのみで動作する、より保守しやすいコードになりました。

直してもらったスクリプトを動かすと、なんか結果が化けた。マルチバイトのファイル入出力をやるときは読み込んだものを内部表現に decode してから処理し、encode してから吐く、という作法が必要で、Claude はそこまでは気が回らなかったらしい。再度直してもらう。

俺:このスクリプトでは日本語の入出力を扱うので、ファイル入力から読み取った文字列は decode() 関数で内部文字列に変換し、出力時も encode で ISO-2022-JP に変換してから出力したいのです。そのあたりを修正してもらえますか?

Cl: はい、適切な文字エンコーディング処理を追加します。ファイル入力時にdecode()で内部文字列に変換し、出力時にencode()でISO-2022-JPに変換するように修正します。

修正が完了しました。文字エンコーディングを適切に処理するように以下の変更を行いました:

主な修正点

  1. use utf8;を追加: ソースコード内の日本語文字列を適切に処理
  2. 標準出力のエンコーディング設定:

    perl
    binmode(STDOUT, ":encoding(iso-2022-jp)");


    これにより出力時に自動的にISO-2022-JPに変換されます
  3. 入力ファイルのエンコーディング指定:
    • diary.dat: <:encoding(euc-jp) で開く
    • diary.cachein: <:encoding(euc-jp) で開く
    元のスクリプトがEUC-JPベースのシステムで動作していたと思われるため、入力はEUC-JPとして扱います
  4. 文字列処理の簡素化:
    • convert_to_jis関数を削除
    • 日本語文字列は内部文字列として保持
    • 出力時にbinmodeの設定により自動的にISO-2022-JPに変換

文字エンコーディングの流れ

  1. 入力: EUC-JPファイル → decode() → 内部文字列(UTF-8フラグ付き)
  2. 処理: 内部文字列のまま処理
  3. 出力: 内部文字列 → binmode設定により自動的に → ISO-2022-JP

この修正により、日本語の入出力が適切に処理され、文字化けなく動作するはずです。もし入力ファイルのエンコーディングが異なる場合は、:encoding()の部分を適切なエンコーディング名に変更してください。

ソースを見ると、my の付け方が間違っていて変数のスコープが変になっている箇所がいくつかあったので手で直す。しかしミスはそれくらいで、そこを直したらちゃんと動いた。素晴らしい。

自分で調べて書き直していたらもっとずっと時間がかかっただろう。こういう仕事をさせるには良いツール。


中身は、「アンテナ」という呼称で昔よく使われていた、いろんな人のブログの更新時刻を監視するもの。はてなアンテナとかは使わず、友人が作ったシステムを一部流用させてもらい、動かしている。しかし四半世紀も使っていたとは感慨深い。HTMLの文字コードが ISO-2022-JP というのも今となっては化石。更新時刻はチェックしているものの、肝心のブログはたまにしか読みに行ってなかったりする。

そこに登録していたお友達のすけさんさんが、『見たこともない宇宙』を宣伝してくださっていた。ありがとうございます! 長らく気づかなくてすみません。