ChatGPTとperl：古のCGIスクリプトを現代的な環境に合わせて再生させようとした話

![oldperlprogrammer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/eaf1802e-4a82-1249-0163-59bd46820598.png)
**「jcode.plが見つからん…じゃと？ どういうことじゃ？？」**

# はじめに
Perlで作られたCGIスクリプトは、今では時代遅れであると見なされることが増えているようですが、それでもいまだに多くのウェブサイトで稼働し続けています。これらのサイトを新しいホスティングサービスに移行しようとすると、仕様の違いから問題が生じることがあります。その対処は、多くの人にとって面倒なものでしょう。

2023年はChatGPTの登場が大きな話題となりました。コードの解析や修正、さらには新しい技術への移行作業を強力にサポートできることが示されてきています。新しい情報を追いかけるだけでなく、CGIに依拠する古いウェブサイトを対象に温故知新を図るのにも使えるのではないでしょうか?　挑戦してみることにしました。

# お題

適当にググってみると、20年以上前のperl CGIに関するQ&Aの記事を見つけることができました。

* [jcode.plでデコードしたのに文字化けしてしまうのは・・・・](https://www.tohoho-web.com/lng/200001/00010195.htm)

<!-- chatgpt
https://chat.openai.com/share/63771c8c-155f-453d-8847-93a97415e6eb -->

懐かしい香りがいっぱいのシンプルなCGIスクリプトが掲載されています。

```
#!/usr/local/bin/perl
require "cgi-lib.pl";
require "jcode.pl";
&ReadParse;
$Name = $in{"Name"};
&jcode'convert(*Name,"euc");

print"Content-type\: text\/html\n\n";
print <<EOM;
<HTML><HEAD><TITLE>テストのＣＧＩページ</TITLE></HEAD>
<BODY>
<INPUT TYPE="TEXT" VALUE="
EOM

print $Name;

print <<EON;
">
</BODY>
</HTML>
EON
```

シンプルなスクリプトで、テストの素材として手頃そうです。

## ChatGPT 提案1

さて、これをまず今のperlのコーディングスタイルで書き直したいと思います。さっそくChatGPTにプロンプトを与えてみましょう。
![1_231122.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/899db5e5-07b8-4d05-cdd8-bfaed7a1907c.png)

すると、すぐに次のようなスクリプトを書いてくれました。

```
#!/usr/local/bin/perl

use strict;
use warnings;
use CGI;
use Encode;

my $q = CGI->new;
print $q->header(-type => 'text/html', -charset => 'UTF-8');

my $name = $q->param('Name');
$name = encode('utf-8', $name);

print <<EOM;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>テストのCGIページ</title>
</head>
<body>
    <input type="text" value="$name">
</body>
</html>
EOM
```

ぱっと見ではマトモそうなスクリプトですが、実行できるのでしょうか。手元のlinux機にはApacheがインストールしてあるので、すぐに試してみることにします。
![1_231122a.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/df290463-bd22-64f2-b393-98138d982bf5.png)

どうやら動作しているようですが、残念ながらログには警告メッセージが書き込まれているようです。

```
Use of uninitialized value $name in concatenation (.) or string at chatgpt.cgi line 14.
```

警告メッセージが出っぱなしというのも気持ちが悪いので、なんとか対処したいところです。

## ChatGPT 提案2

![a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/0597a623-a998-cea1-37f6-d8e96abb6c1a.png)

すると次のような修正版が提示されました。

```
#!/usr/bin/perl

use strict;
use warnings;
use CGI;
use Encode;

my $q = CGI->new;
print $q->header(-type => 'text/html', -charset => 'UTF-8');

my $name = $q->param('Name') // '';  # Initialize $name to an empty string if it's not defined
$name = encode('utf-8', $name) if $name;

print <<EOM;
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>テストのCGIページ</title>
</head>
<body>
    <input type="text" value="$name">
</body>
</html>
EOM
```

違いはここだけ。
```
my $name = $q->param('Name') // '';  # Initialize $name to an empty string if it's not defined
$name = encode('utf-8', $name) if $name;
```

その内容についてChatGPT先生にご教示いただくとしましょう。
![aa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/261946d6-fdb8-1110-ce7a-613d17d8732a.png)

`//`という演算子は私にとって初見でした。20年以上perlプログラムで仕事をしている私ですが、今もってこうして「今初めて知ったのだ!」という状況に遭遇することがあります。つくづくperlプログラミング侮るべからず。そしてそういう知見をさりげなく見せてくれるChatGPT恐るべし。

# どうせならCGIではなくWAF(Web Application Framework)で仕立て直せないか？

このように、perlで書かれたCGIスクリプトの改良にChatGPTが役立ちそうだというのは分かりました。しかし、そもそも2023年においてはCGIという仕組みそのものが余り流行っていないように見えます。いまどきはWeb Application Frameworkというものを使うらしいですが、perlでも対応できるのでしょうか?

![1_231120.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/67c54da7-728e-4702-0953-29005c068690.png)
![1_231120a.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/30a2e1df-f7fa-4c1d-3765-b2e4f8dd0aaa.png)

こんな感じで、どうやらperlベースのWAFがいくつか存在すると分かります。

## Mojoliciousベースのスクリプトを書いてもらう

こうして見出したperlベースのWAFについてざっくりググってみると、[Mojolicious](https://mojolicious.org/)が使いやすそうです。当該のCGIスクリプトをこのWAFで仕立て直せないものでしょうか。

再度ChatGPTに頼りましょう。さきほどCGIの改良を試みたスレッドに、つづけて次のようなプロンプトを追加投入します。

![1_231120b.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/50fd22ac-6586-7833-1cbd-67ba340e41ec.png)

```
#!/usr/bin/env perl                                                                                                                                          
use Mojolicious::Lite -signatures;

# Route leading to a handler that processes the 'Name' parameter                                                                                             
get '/' => sub ($c) {
    my $name = $c->param('Name') // '';
    $c->render(template => 'index', name => $name);
};

app->start;

__DATA__

@@ index.html.ep
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>テストのCGIページ</title>
</head>
<body>
    <input type="text" value="<%= $name %>">
</body>
</html>
```

コードを提示してくれるだけでなく、その内容や使用法についても解説してくれるのが助かります。

![1_231124.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/0e63ebf5-8e09-ef83-7b2a-dc6920857169.png)

言われたとおりにスクリプトを実行して、ブラウザで見てみます。最初のCGI同様、ちゃんとwebページしていることを確認できました。

# Perl、ChatGPT、温故知新

最先端の流行を追いかけるのも結構なことですが、古いものの中にも光るものはあります。それらを新しい革袋に詰め直す作業もまた有意義と言えるでしょう。

とはいうものの、技術者・研究者としては古いもののお守りには食指が動きにくいのも確かでしょう。
![old_and_young_man3a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383429/89bc8147-43bc-2eb6-f1a1-dc46fda880b9.png)
**「なんとかならんかのう」**
**「いまさらperl？ まあ爺ちゃんがどうしてもというならやるけどさ。せめてPHPにしない？」**

そうした退屈な作業こそ、機械にうまく任せてみればいいんじゃないでしょうか。ChatGPTのコーディング代行能力はなかなかのものになっています。

# まとめ

2023年現在でもperlは健在です。perlが得意なテキスト処理の重要性はむしろ増しています。perlはCGIだけでなくWAFにも対応できます。「古い」リソースを新しい時代に適応するよう仕立て直すことは充分に現実的なアプローチであり、その目論見を現実化するためにAIは有効に活用できそうです。

一連の検証には、手元のWindows機とubuntu20.04機を用いました。perlのバージョンは5.30.0です。
ChatGPTは有料版のGPT-4にプラグインのWebPilotとLink Readerを導入しています。コードの作成だけでなく、序文のテキスト生成とイラスト作成にも活用しました。これらを利用したのは2023年11月20日前後であり、時期が変わればこれらの結果は大きく変わる可能性はあります。