CGIを乗り越えて

長年の課題

手元の記録によると、僕は2013年の5月1日に渋谷へ打ち合わせに行って、その帰りにプログラミング関連の本を3冊買い込んでいる。

おそらくは心身のストレスがすごく溜まって、その反動のように、なかばヤケになって「仕事に全然関係ないことを全力でやってやる!」みたいになっていたのだとおぼろげながら思い出す。

実際には、その前からもプログラミング入門の意志を持ってはいたけれど、僕がその勉強を2013年の5月から始めた、とよく言うのは、ひとまずそれらの書籍購入が理由なのだと思う。

とはいえ、その後もしばらくの間は手探り状態というか、本格的に学びたいようであり、もっと機が熟すのを待ちたいようでもあり、あるいは具体的にやりたいことがあるようであり、無いようでもあり、という日が続くのだけど、そんな中で何となく見えてきた目標は、たとえば「gitを使えるようになりたい」とか、「tDiaryをインストールして日記を書きたい」とかだった。

gitは当時、僕がよく目にするプログラマー同士の会話でしょっちゅう名前が挙がっていたりして、自分も使いたいと思ったということだろう。

一方のtDiaryは、2005年頃から使っているはてなダイアリーとの繋がりで、以前からその存在を知ってはいたけれど、その雰囲気のやわらかさとは相反するような「玄人っぽさ」が感じられ(使ってる人は皆その道のプロ、みたいな)、いつかは自分でそれを設置してみたい、もしそれが出来たら、自分も一段階次のレベルへ進んだと言えるはず、みたいに感じていたのだと思う。

その後、gitの方はなんだかんだで最低限の操作はできるようになったものの、tDiaryの方は何度トライしても、そのたびに「ああ、駄目だ。まだ俺には難しすぎる。わからなすぎる」と挫折した。

tDiaryは今なおどんどん進化を続けていて、単に「tDiaryで日記を書きたい」というだけなら、特別な技術的知識はほとんど無くても使えるようになってきているようなのだけど、僕の目的は「技術力がついたことの証としてtDiaryを自力で設置する」ということだから、公式サイトのドキュメントをもとに標準的なインストールができなければ目標を成し遂げたことにはならないし、それが何度やってもできなかった。

CGIがわからない

さて、ではtDiaryの設定が「難しい」と僕が言うとき、具体的に何が難しいのかと言うと、いろいろある中でも一番の難関は「CGIがわからない」ということだろう。

CGIというのは、知ってる人にはあまりにも前提的な技術であるかもしれないけど、現時点でそれについて何も知らない人が、一からそれを学ぶためには、これという入り口が実はない。

「そんなの、ネットを検索すればいくらでも情報が出てくるだろう」と思われるかもしれないし、実際に情報自体は少なくないのだけど、その大半は、いにしえの環境やWindowsマシンによる操作を前提にしたものであって、2015年を生きる僕の、さらにはMacによる操作を前提にしたCGI入門の記事なんてそうそうない。というか、ない。

よって必然的に、そうした古かったりWindows前提だったりする記事を自分の環境に読み替えて、サンプルコードなどを実行してみるわけだけど、それですぐに動くなどということはまず無くて、またそのエラーをもとに検索を重ねても、あちこちをたらい回しされるばかりで解決には至らず、やがて気分的にも体力的にも徒労がつのり、結局毎回「ああ、駄目だ。まだ俺には早かった」となってしまう。

この「自分の環境にフィットした情報がない」「試しても動かない」ということが、僕にとってのCGIの難しさだった。

CGIを勉強する意味

そのようなことを言うと、「というか、そもそも今、CGIを勉強する必要なんてあるか?」と笑われるかもしれないのだが、もちろん勉強する意味はある。

たしかに、CGIはもう必要とされていない技術かもしれないし、今後作られる新たなプロダクトでそれが採用されることも少ないかもしれない。

しかし問題は、CGIそれ自体を使うかどうかではなく、CGIを扱う能力を持てるかどうか、なのである。
言い方を変えれば、CGIすら理解できない人間に他の何がわかるのか? ということだ。

CGI自体の知識は無くて良いとしても、それを「理解しようとしても出来ない」という人に、それ以外の技術を理解できるはずがない。

だから問題は、「使うか/使わないか」でもなければ「知っているか/知らないか」でもなく、CGIを「理解できるか/できないか」であり、僕は「CGIを理解できる」という能力を、いわば免許/パスポートのように手に入れて、それを持って次のステージに行きたいと思っている。

念のために言うと、それは「CGIを理解するまで他のことをしない」という意味ではない。むしろ、RubyなりGoなりDockerなりという進行形の技術に目を向けつつ、その一方でCGIの仕組みもちゃんと知っておきたいということだ。

さらに言っておくなら、「CGIなんてもう使わないよ。勉強する意味なんてないよ」と言う人の多くは、自分ではしっかりCGIを理解しているに違いない。そしてその人自身がCGIの技術を習得する前の状態に戻れない以上、その勉強が不要であると証明することは困難だ。

CGIについて触れずに充分なプログラミング技術を学習できる方法があるのであれば、その方法の中のどの要素がCGIを代替しているのかを明確に示すべきであるし、それがないまま学習者の向かう先を否定しても、相手の気持ちをくじくだけだから、どうか優しく見守ってほしいと思う。

直接的な乗り越え

CGIをようやく克服できたのは今年の2月の初めで、以下のムックの冒頭に書かれていた小飼弾さんの記事と、このブログではよく紹介している結城浩さんのPerl入門書に書かれていたCGIの項目がきっかけになった。

Web開発の基礎徹底攻略 (WEB+DB PRESS plus)

Web開発の基礎徹底攻略 (WEB+DB PRESS plus)

新版Perl言語プログラミングレッスン入門編

新版Perl言語プログラミングレッスン入門編

といっても、単純にこれらの中に書かれているコードをそのまま実行しても、やはりそれまで同様、すぐには動かなくて、いろいろ自分なりに手を入れて、ようやく動かすことができた。

そしてその過程を後から振り返ると、結局のところ、僕の環境でCGIが動かなかった原因は、以下の要素が単発ないし複合的に生じていたことに尽きると思う。

1. サーバーの設定でCGIの実行権限を適切に設定していない。
2. ファイルのパーミッション設定で実行属性が付いていない。
3. PerlスクリプトCGI.pmを使う際にyumperl-CGIがインストールされていない。

逆順で説明すると、3番はそれこそ今後作られるプログラム/プロダクトにはあまり関わらない知見かもしれないけど、結城浩さんの書中にあったサンプルコードに、 CGI.pm をuseしているPerlスクリプトがあって、それが動かない原因を探し続けて、ようやくこれに行き着いた。

同書はきわめて明快&簡潔に書かれているので、これでわからなければ読者のほうが悪い、というぐらいのものだけど、それでも本の通りに書いたコードが動かないので、逆に原因を絞り込みやすかったとも言える。

特徴的なのは、後述の2点がサーバー設定の問題であるのに対し、これは「CGI.pm」というPerlのモジュールがちゃんとインストールされているかどうか、というPerlの問題であったことだろう。

CGIPerlがよく結び付けられて語られることもあって、「CGI」という技術全般の話と、Perlモジュールの「CGI.pm」の違いを知らないまま、ずっとこんがらがっていた。

わざわざ「yumperl-CGI」と断っているのは、plenv経由でセットアップしたcpanmでCGI.pmをインストールしてもスクリプトは動かなくて、yumperl-CGIを入れて初めて動いたからなのだけど(僕の環境ではplenvでsystemの他に5.20.0が入っていたので、その両方にcpanmでCGI.pmを入れたが動作しなかった)、この辺についてはまだ充分に理解できていないので、今後より詳しく把握したい。

いずれにせよ、その結城さんのサンプルコードはトータル10行程度の最高にシンプルなコードだったから、それだけにこれが動かない間は頭が混乱し続けたし、動いたときにはものすごく嬉しかった。

また、2番のファイルのパーミッションについて理解できたのは、上記の弾さんの記事がきっかけで、ここにもサンプルコードが併記されていたのだけど、その説明文の中に

chmod a+x date.cgi

で実行属性を付ければ(略)アクセスできます。

という記述があった。

chmodというコマンドについてはドットインストールのUNIXコマンド講座で見かけていて、そこでは777とか644といった番号による設定が重点的に説明されていたけど、基礎はこれを見るだけでも充分理解できる。

それを知った上で、上記の説明を読んでいたので、ここでようやくCGIのファイルには実行属性というものが必要なのだと明確にわかった。

腑に落ちるまでやる

とはいえ、CGIを動かそうというときに一番問題になるのは、やはり1番のサーバーの設定に関することだと思う。

サーバーと言ってもいろいろあるだろうけど、ここではapacheのことを念頭に置いて言うと、個人的にはとにかく /etc/httpd/conf/httpd.conf ファイルの中の

AddHandler

ExecCGI

の2点さえ各自の状況に応じて適切に記載できれば、CGIは動くと実感している。

……なんて、最大限簡潔に書いてはみたけれど、何しろその2点(AddHandlerとExecCGI)の書き方というのは、内実を知らない人にとっては無限大の組み合わせ・選択肢を考えることができてしまい、それに加えて、ネット上には太古の昔から脈々とアップされ続けてきた玉石混交のapache情報が入り乱れているので、迷子になるなと言うほうが無理がある。

そのような状況にあって、じゃあ僕自身はどうしたのかと言うと、ネットで調べて集めまくったhttpd.conf の書き方を一気に記載してみて、もしそれで動いたら、そのうちどれを元に戻しても(書かなくても)動くのか、あるいはどれを記述しなかったら動かなくなるのか、ということを一つ一つ調べ(比べ)続けた。

その際には、実行する環境によってバラつきが出ないように Vagrantでサラの環境を作って、条件を合わせて何度も試して、それでようやく自分なりに納得することができた。

CGIに関する情報は上記のとおり、古かったり断片的だったり、あるいは今のぼく自身がそうであるように、生半可な知識のままアップされてしまった情報だったりして、正直、まったく役に立たなかったり、場合によっては関係のないところへ誘導されてしまうことも少なくなかった。

それは正しい情報を僕が間違って解釈したから、ということもあるかもしれないし、情報自体が間違っていたこともあるかもしれないけれど、どちらにしても言えることは、他人が上げた情報はあくまで「参考」にするものであって、最後に頼りになるのは、自分の中で芯から腑に落ちた理解であるということだ。

この「自分の中に作り上げた理解」が土台にあれば、もしその理解を逸脱する現象が生じても、それらの差分を通して、つまり自分が知っていることと実際に生じている状況との「違い」の中にエラーの原因があると見込んで、追求していくことができる。

逆に言えば、そのような差分を抽出するための土台・基盤ができるまでは、「どの情報を信じたらいいのかわからない」という状況を漂い続けることになるし、結局のところ冒頭に書いた「ああ、駄目だ。まだ俺には早すぎる。難しすぎる」という挫折の数年間は、そうした土台がないゆえの漂流時代でもあった。

大局的な乗り越え

直接的なCGIを理解するきっかけは上記の2冊だったけれど、より大きな意味で、僕をその克服へ導いてくれたのは、サーバー/Linuxの独習だったと思う。

僕はまだまだそれらについてよく知らないが、それでもLinux操作の基礎に触れ、それに対する無知の度合いや、苦手意識や忌避感を薄れさせていく中で、「今生じているこの問題の原因は、もしかしたらこれではないか?」という予想を、以前より早く、高い精度でつけられるようになってきた。

そのような、いわば得意意識(苦手意識の反対)が育ってくると、今度は何回トライに失敗して、そのたびに力尽きて倒れてしまっても、しばらくしてから「もしかして……あれが原因かも?」と、湧き立つような新たな仮説とともにムクリと体を起こすことができ、その繰り返しのうちについには正解へ辿りつけるようになる。

もしサーバーの勉強を始めていなかったら、CGIまわりの用語や概念はまだ不明なものだらけで、トライしてもいまだに「早すぎる」となっていただろう。
僕にとってサーバーの勉強は、CGIを理解するためのものではまったくなかったけれど、巡り巡って、それが一番の助けであり力になったのだと感じる。

サーバーの勉強をなぜ始めたのかと言えば、それ系の話をしている人たちが実に楽しそうで、刺激と面白さに満ちた時間を過ごしているように見えたからで、自分もそれに加わりたいと思ったからだった。

これについては、以下の記事の最後にその心境を非常に上手く表している引用文を抜粋している。

楽しそうだから、と思って始めた勉強が、別のところに存在していた長年の懸案・課題を解決する助けになった、というのは我ながら良い話だと思うけど、このCGIの克服と、サーバーに関する微々たる得意意識の獲得とが、さらには冒頭に示した「tDiaryを動かす」という積年の目標をついには果たすことへ繋がっていくのだから、その話はもっと面白い。

その辺りの具体的なことについては、また時間ができたら書きたい。