オープンソースソフトウェア貢献への道のり

はじめに

このエントリーでは、最近私が書いたCatalyst::Plugin::XMLRPCのライブテストが、Catalystのtrunkのコードにマージされるまでのストーリーが書かれています。オープンソースソフトウェアへ一度でも貢献してみたいと考えたことのある方をインスパイアできればと思って書きました。おてもとにCatalyst::Plugin::XMLRPCとCatalystソースコードを用意して、このエントリーを読んで頂くと理解しやすいかと思います。

オープンソースソフトウェア貢献への憧れ

昔から憧れていたことがあります。それは、オープンソースソフトウェアに貢献することです。でも、現実を見つめると、これってなかなか難しい。こんな面白い時代に生まれてきたのに、何もできない自分が悔しかった。

オープンソースソフトウェアは、実力が無いと相手にされない厳しい世界。しかし、この世界に少しでも自分の身を置くことができれば、素晴らしい経験ができるはず。そう最近強く思うようになりました。

CPANという偉大な環境

ここで少し脱線します。

私がPerlに魅力を感じるようになった1つの理由は、やっぱりCPAN。私は、SixApartの宮川さんがここまで凄腕のHackerになられたのは、CPANの存在が非常に大きいのでは?と思っています。(それだけが宮川さんの成功の要因ではないことはもちろん理解しています。) この世にCPANが無ければ、今の宮川さんはないと言っても言いすぎではないと思います。つまり何が言いたいのかというと、CPANはHackerを育成する最高の環境なんだということです。CPANは単なるモジュールの塊なんかじゃありません。プログラマに最高の「環境」を与えてくれます。

CPANの何が良いかというと、

  1. ネットワークベースの知的財産共有アーキテクチャ
  2. 大きいモジュールから小さいモジュールまで千差万別
  3. 誰でもCPAN Auhtorになれる権利
  4. 英語

といったところでしょうか。

CPANが誕生したのは今から20年も前のこと。20年も昔にこんなに素晴らしい知的財産共有アーキテクチャが考案されていたのか?と考えると、何かワクワクしてきます。20年前にはもう私は生まれていましたが、コンピュータの存在すら知らない幼児でした。正しくは、10年前です。失礼しました。

CPANで公開されているモジュールは、ノウハウの塊です。良質なモジュールのコードを読むことで、ノウハウを吸収できます。が、しかし、そんなことは分かっていても、なかなかノウハウを吸収するのは難しい。いきなりメジャーで大きなモジュールからノウハウを吸収するのはしんどいです。幸い、小粒のように小さいモジュールがCPANには沢山あります。私はそのような小さなモジュールから少しずつコードを模写して盗んでいけば良いのだと思います。本当に美しいコードを模写していると、気分が良くなります。(私の場合、どこにでも売っている普通のノートに鉛筆で丁寧に写し取る作業をします。キーボードではなく、鉛筆で模写する方が心に残りやすいです。)

誰でもCPAN Auhtorになれるといっても、私はまだCPAN Authorのアカウントを持っていません。でも、冷静に考えると、CPANに貢献するためには、CPAN Authorでなければならないということは全くありません。最近、それに気がつきました。ちょっとしたバグレポートからでも良いのです。つまり、段階を踏む必要があると感じました。例え、今CPAN Authorのアカウントを取得し、何かモジュールを公開しても、公開したモジュールを使ってもらえるかわかりませんし、第一、一度公開してしまうと「メンテナンス」という重大な責任が発生します。(新しいソフトウェアを生み出すのは、誰でも喜んでやりたがるものですが、メンテナンスとなると誰もがやりたくなくないものです。) やみくもに憧れのCPAN Authorになっても、今の自分ではCPAN Authorとしての役割を十分に果たせないだろうと考えました。もっと気軽にCPANに貢献していく方法を模索する必要があります。

最後に英語。何と言っても世界で通用するのは今のところ、英語です。私は大学でドイツ語を第二外国語として勉強しましたが、入門コースにも関わらず、二度も再履修してようやく単位をとった人間です。動詞が色々変化するのが凄い大変で、嫌になりました。ドイツ語の単位を取ってから、なぜかスペイン語に興味を持つようになり自力で勉強しました。たまたまNHKでやっていたスペイン語入門の番組で聞いたスペイン語の発音が気に入ったのがきっかけです。スペイン語もドイツ語と同様に、主語によって動詞の語尾がやたら変化したり、名詞の性の区別があったりと、非常に面倒な言語だなぁという印象を持つようになりました。長々とどうでもよさそうな事を言いました。つまり何が言いたかったのかというと、英語は他の言語と比べてとてもシンプルだということです。ドイツ語やスペイン語を知ると、いかに英語がシンプルな言語なのかが良くわかります。(言語学者じゃないので偉そうなことは言えませんが。)

CPANを活用することで「生きた」英語を勉強できるのではないでしょうか。ただし、英語がネーティブでないHackerが書いたドキュメントは特有のナマリがあるので、ちょっと注意が必要かもしれません。しかし、これからの時代は、ネーティブでない人が書いた英語もちゃんと読める力が必要になっていくと思います。(笑

Catalystに興味を持つ

ある日、宮川さんのblogを見ていると「Catalyst」という聞きなれない言葉が目に入りました。その時は、CatalystPerl用のMVCのWebアプリケーションフレームワークであるということしか頭に残りませんでしたが、その後、Catalystが様々なblogで取り上げられているのを見て、注目されていることにようやく気がつきました。はてな技術発表会でもid:naoyaさんがCatalystの実演をされたのを見て、

Catalystにちょっと投資してみるか」

と思うようになりました。ここ最近まで、Catalystで作ったサンプルアプリが取り上げられているblogのエントリや、CPANにあるCatalystのマニュアルを片っ端から印刷して読み漁ってました。これでなんとなくCatalystがどいういったフレームワークなのかわかるようになりました。(まだまだ勉強不足ですが。(汗 )

最近では、もっとCatalystに興味を持つようになり、Catalystメーリングリストにまで参加するようになりました。メーリングリストに参加した当初は、携帯電話に転送するようにしていましたが、あまりにもメーリングリストが活発だったので、転送はしないようにしました。私は、このメーリングリストの活発さから、まだまだこれからもCatalystの改良が進んでいくと思いました。

Catalyst::Plugin::XMLRPCがすべてのはじまり

CatalystにはXML-PRCを簡単に実装できるプラグインがあります。そう、Catalyst::Plugin::XMLRPCです。このプラグインid:naoyaさんの はてなブックマークで知りました。id:naoyaさんも注目されているプラグインってどんなのだろう?と思い、試しにインストールしてみましたが、残念ながら失敗。その時はうまく動作しませんでした。私が悪かったわけではなく、プラグインのバグでした。

これはチャンスだと思いました。

そこでこのプラグインの作者(Sebastian Riedelさん)に英語でバグレポートしてみました。この時はCatalystメーリングリストにはまだ参加していませんでした。Sebastian RiedelさんがCatalystの開発メンバーの中でも重要人物であるということに、最近気がつきました。(遅っ

私の意図が通じたようで、バグフィックス版のバージョン0.05がCPANにアップされました。この時、「バグレポートでも十分にCPANに貢献できる」と確信しました。バグが修正されるだけでも、今までに無い達成感が得られました。

Catalyst::Plugin::XMLRPCのライブテストを書く

携帯電話への転送設定をやめてCatalystメーリングリストを見る機会が減りました。数日前、Catalystメーリングリストを見ていると「We need more tests!」というタイトルのメッセージに目がとまりました。何だろう?と思い、読み進めると、Catalystプラグインのテストがちゃんとできていないとのことでした。確かに。Catalyst::Plugin::XMLRPCのテストコードを見ていても、XML-RPCそのものをキチンとテストしているコードはどこにも見当たりませんでした。「ライブテスト」に少し前から興味を持っていたのと、ちょうど暇とやる気(京大での はてな近藤社長からのインスパイア)があったので、頑張ってみることにしました。

まず、Catalyst-5.57/t/*のコードを順番に読み漁りました。「live_」ではじまるテストファイルを読むことで、ライブテストの雰囲気がわかりました。次に、そのディレクトリにあったoptional_http-server.tをノートに模写しました。そのテストコードはライブテストには直接関係しませんが、凄い面白いことをしているのに気がつきました。proveコマンドを知るキッカケになったのも良かったです。

次は、Catalyst-5.57/lib/Catalyst/Test.pmを模写しました。特にimport()とlocal_request()です。模写をしているうちに、local_request()が今回のキモになるなぁと感じました。

local_request()の実装が、このままではまずいことにも気がつきました。というのも、Catalyst::Util::request( shift(@_) ); のコードが邪魔をしていて、このままでは自由にHTTPのリクエストを発行できないからです。このままではXML-RPCを実行できません。そこで、id:antipopさんが昔に書かれた「del.icio.usからはてなブックマークへデータを移行する」を参考にして、ライブテストのはじめにCatalyst::Test::local_request()のシンボルテーブルを操作して、自前のlocal_request()にすり替えることにしました。つまり、リフレクションを使いました。

そんなこんなで、ごにょごにょしていると、なんとかライブテストが機能するようになりました。はじめて機能するようになった時のコードは、めちゃくちゃで、見せられるような代物ではありませんでした。XML-RPCのリクエストのXMLやContent-Lengthのサイズをハードコードしたりと試行錯誤の痕跡がいっぱいでした。

そこで、早速リファクタリングにとりかかりました。リファクタリング時に一番気をつけたのは、Catalystで使われているコーディング規則をできるだけマネするようにしたことです。読みやすくするのと同時に、できる限り手を入れなくても、コードをマージしてもらえるようにするためです。あと、生でテストコードにXML-RPCのリクエストとレスポンスのXMLを書くのはみっともなかったので、「$ perldoc -m PRC::XML」で参考になりそうなコードがないか調べました。すると、as_string()なるメソッドを発見したので、それを利用するようにしました。

リファクタリングが完了し、ここで少し考えました。今ここで、tarで固めてメーリングリストに報告するか、それとも、不要なコードをもう少し整理してからにするか。今の知識では、不要な部分(t/lib/*)を適切にはぎ取る力がないし、何より、今ここに「ライブテスト」が完成したのだから、やっぱりすぐに報告すべき。そう判断しました。

メーリングリストへの報告

早速、tarで固めてメーリングリストにメールを出しました。(この時、tarで固めるのはマナー違反でdiffした結果を送るべきだとはわかっていましたが、不要な部分(t/lib/*)が多すぎてdiffした結果があまりにも見にくかったので断念しました。)

メーリングリストに投稿したメールは以下のような内容です。これで何も反応が無かったら、凄い寂しいなぁと思いながら、返事を待って、夜も遅いので寝ることにしました。

[Catalyst] Live test for Catalyst::Plugin::XMLRPC 0.05

Hi,
I wrote a live test (not perfect, however) for Catalyst::Plugin::XMLRPC 0.05.
I hope the live test meets with the catalyst team's requirements.

To run the live test, please type the following commands at your terminal.

$ tar zxvf Catalyst-Plugin-XMLRPC-0.05.livetest.tar.gz
$ cd Catalyst-Plugin-XMLRPC-0.05.livetest
$ prove -v t/04live.t
t/04live....1..8
ok 1 - Request
ok 2 - Response Successful 2xx
ok 3 - Response Code
ok 4 - Content OK
ok 5 - Request
ok 6 - Response Successful 2xx
ok 7 - Response Code
ok 8 - Content OK
ok
All tests successful.
Files=1, Tests=8,  1 wallclock secs ( 0.88 cusr +  0.12 csys =  1.00 CPU)


Note that the files in the t/lib directory of the archive are copied
from Catalyst-5.57/t/lib.
These files are necessary to achieve live test. (Another better way exists?)

Here is the important files:
- t/04live.t (added)
- lib/TestApp.pm (modified)
- lib/TestApp/Controller/Plugin/XMLRPC.pm (added)


Thanks in advance,
--
Yoshinori Sano

返信:「Perfect, applied and released as 0.06! Thx!」

翌日、PCを立ち上げてメールをチェックすると返信が届いていました。返信の内容は以下の通りです。

Am 28.11.2005 um 14:09 schrieb Yoshinori Sano:

> Hi,
> I wrote a live test (not perfect, however) for  
> Catalyst::Plugin::XMLRPC 0.05.
> I hope the live test meets with the catalyst team's requirements.

Perfect, applied and released as 0.06! Thx!

> Note that the files in the t/lib directory of the archive are copied
> from Catalyst-5.57/t/lib.
> These files are necessary to achieve live test. (Another better way  
> exists?)

I've removed the unnecessary stuff, all we need is a minimal TestApp.

     http://dev.catalyst.perl.org/changeset/2282

>
> Here is the important files:
> - t/04live.t (added)
> - lib/TestApp.pm (modified)
> - lib/TestApp/Controller/Plugin/XMLRPC.pm (added)

Here are some small points you could improve next time: (no big deal,  
but would make my life a bit easier) :)

* Send a patch instead of a tar
* Update Changes and version
* Add your name to the Authors list
* Remove unnecessary files


--
sebastian

このメールを読んだとき、めちゃくちゃ嬉しくなりました。trunkのソースを見てみると、ほとんどそのままのコードが反映されていました。奇跡が起こったと思いました。

少し怒られましたが、このコメントも私にとっては非常に嬉しいものでした。次も何か貢献したくなるような、お叱りの言葉ですね、これは。よく読んでみると、「Add your name to the Authors list」って書いてあります。いきなりそんなことをするのは大胆で、日本人の私にはそんな勇気無いですよ。(汗

おわりに

ここまで長い文章を読んで頂きありがとうございました。

CPANには、オープンソースソフトウェアの技術者として貢献できることが沢山あります。一人でも多くの技術者をインスパイアできれば幸いです。

追記 (11/29 22:55)

Catalyst::Plugin::XMLRPC 0.06CPANからダウンロードできるようになりました。「AUTHOR」の所に自分の名前が載ったのを見て、改めて頑張って良かったなぁと思いました。これが今回の変更箇所です。