2024年11月21日
「不慣れなソフトウェアのコードを解読し、その内容を正しく理解すること」は、業務のなかでエンジニアが苦労することのひとつです。迷宮のように入り組んだソースコードを読んで、意味がわからず途方に暮れたり、自分のスキルの無さを嘆いたり――。こうした経験を持つ方も少なくないのではないでしょうか。
LaravelのスペシャリストでありOSSへのコントリビューションも行う武田憲太郎さんも、かつては「コードを読むのが苦手だ」と感じていたといいます。しかし、OSSに携わるようになってから自身のスキルやマインドに大きな変化があり、コードを読む速度が向上したのです。はたして、武田さんに起きた変化とは何だったのでしょうか。そして、OSSのコードを読むことで生じる、業務へのポジティブな影響とは。
武田:もちろん、ありましたよ。はっきり申し上げますと、むしろ読むのを苦手に思っていた時期のほうが長いくらいです。エンジニアとして働いて20年ほどになりますが、15年目くらいまでは苦手意識が強かった。「コードを理解する速度が上がったな」と思えるようになったのはそこから後でした。スキル上達には複合的な要因が絡みますが、私の場合は理由のひとつとして、OSSのコードを読むようになったのがかなり大きいです。
かつて、私は業務のなかでLaravelやSymfonyといったフレームワークではなく、いわゆるオレオレフレームワーク(個人や企業が独自制作したフレームワーク)で開発をしていました。そうしたなかで、あるプロジェクトでLaravelを使う必要性が生じたんですよ。
Laravelを触っているうちに、オレオレフレームワークを長く使っていたこともあり、次第に「OSSのフレームワーク内部では、どんな処理をしているんだろう?」と気になってきました。そこで純粋な好奇心からLaravelのコードを読むことにしたわけです。
武田:言葉が悪いですが、最初は「なんなんだ、このふざけたコードは」と感じました(笑)。というのも、Laravelというフレームワークは徹底的に、学びやすさと使いやすさを重視して設計されています。そして、ユーザーがとにかくイージーに使えるように、フレームワーク内部ではわりとむちゃな実装をしている箇所も多いです。なぜ、こんなことをやっているんだろうと思っていました。
ですが、あるタイミングで「言語の初心者であっても、学びやすく使いやすい」というコンセプトを、Laravelは徹底的に貫いているのだと気づきました。むちゃだと思っていた実装の目的はこれだったのかと、腑に落ちたわけですね。その後、Laravelのコンセプトを念頭に置いてコードを読んでいくと、以前よりすっと頭に入ってくるようになりました。
武田:ソースコードは、そのソフトウェアの設計思想を体現するためにあります。
PHPの世界では、Laravelの他にSymfonyというフレームワークもよく使われています。Symfonyは柔軟でカスタマイズ性の高い設計を重視しているのですが、構成が複雑であり学習コストが高め。LaravelとSymfonyとではコンセプトが異なります。
もし仮に、Laravelの良い設計の一部分を切り取ってSymfonyに移植したとしても、そのまま良い設計になるわけではありません。むしろ、フレームワークの目的がちぐはぐになってしまい、コードを読み書きするのにも悪影響が出ます。良いコードとは、筋の通ったコードなんです。
武田:その考えに至ってから、コードとの向き合い方も変わりました。
私がコードを読むことへの苦手意識があったのは、実のところシステムのコンセプトを理解する作業がうまくできていなかったのではないかと思うようになりました。コードを読むこととコンセプトを理解することは両輪のような関係で、どちらか一方が欠けてもうまくいきません。ただ、こう考えられるようになったのは決してLaravelのコードを読んだことだけが理由ではなく、そのベースにはそれまで習得してきたさまざまな知識があったからこそだと思います。
システムのコンセプトを理解することの重要性を、私は一緒に働く方々に常に伝え続けています。そして、この話を参考にして実践してくれる方のほうが、その後の成長スピードも明確に速くなりますね。
武田:いくつもありますが、一番は読みやすさに対する配慮ですね。OSSのコードというのは、強制的に世界中のエンジニアの目に晒されます。もしも、あるソフトウェアの関数名や変数名などがあまり良くないとか、コード内のコメントが不足している状態ならば、世の中にいるコントリビューターの誰かが直してしまうんですよ。だから自然と、読みやすいコードになっていきます。
もちろんこれは、コントリビューターやユーザーがたくさんいる人気のソフトウェアに限ります。あまり人気のないOSSであれば、そのコードを読む人や直す人の人数も少ないですから、改善の力学が作用しにくいです。
武田:仮に業務のなかで、良くない設計や実装を見たとします。何も知識がなければ、「汚いことはわかるが、どう直せばいいのかわからない」となり、途方に暮れてしまいますよね。ですが、OSSのコードから多くのことを学んでいると「LaravelやSymfonyならばこうなっているから、この汚い設計や実装をこう直せばいいんじゃないか」と考えることができます。
武田:お手本を知っているということは、克服する方法もわかるということ。つまり、エンジニアとしての引き出しの多さにつながります。もしかしたら、予算やスケジュールなどの都合でそのシステムをリファクタリングする時間を確保できないかもしれませんが、それでも「このシステムを改善する方法を私は知っている」というだけで、精神的には相当楽な状態で働けるわけです。
また、OSSの世界ではコントリビューター同士のやりとりが行われますが、それらを見ることで、他者にわかりやすく説明するために必要な要素を学ぶことができます。自分自身がIssueやPull Requestなどを発行する際に、説明文として何を書くべきかの参考にもなるはずです。
武田:「Some traits of database tests do not close the connection even after the test is finished」というIssueが印象的です。LaravelのDatabaseMigrationsやDatabaseTruncationトレイトがテスト完了後にデータベース接続を閉じず、接続が残ってしまう問題が発生していました。この問題を解決するために、私は「[10.x] Disconnecting the database connection after testing」というPull Requestを発行し、マージされました。しかし、この修正によって他の箇所が壊れてしまったため、リバートされることになりました。
そのIssueのバグを最初に踏んだのはPHPコミュニティで有名なmpywさんだったのですが、私とmpywさんは「今回は残念だったけれど、いつかこの問題を再修正したいね」と言っていたんですよ。そんな折に、LaravelのコミッターであるMior Muhammad Zakiさんがドラフト状態の「[11.x] Allows to persist database connection between tests and only reset PDO in afterClassTearDown()」というPull Requestを作り始めました。
最初は何をしているのかよくわかりませんでしたが、コードをよくよく見ていくと「もしかして、私とmpywさんが苦労したバグを、別のアプローチから解消しようとしているんじゃないか」と気づきました。最終的にはこのアプローチもうまくいかずPull Requestはクローズされましたが、問題の解決に向けて複数のコントリビューターたちが議論を重ねる過程を身をもって体感できたため、非常に学びが多かったIssueでした。
武田:仕事で経験する開発プロジェクトは、たとえば予算の都合やクライアントの意見など、エンジニアの力ではどうしようもない原因によって方針が変わってしまうケースもあります。
しかしOSSではコードがすべてであり、良い設計や実装を示せば必ず取り入れてもらえます。すべてのエンジニアは、コードの下に平等です。だからこそストイックな世界ではありますが、OSSの世界で行われているコミュニケーションを見ると、エンジニアがスキルアップするためのヒントがたくさん詰まっています。
武田:OSSを選ぶ基準から話すと、何より大切な条件は、自分が興味を持てるOSSであることです。基本的にはプライベートの時間を割いて読むことになるでしょうから、興味のあるものでなければ絶対に続きません。
そのうえで、適度に利用者数が多くて、適度に歴史の長いもの。利用者数が少な過ぎると人の目にあまり触れていないので、コードが洗練されていないです。一方で、歴史があまりにも長過ぎるとレガシーな部分があるとか内容が複雑過ぎるという課題が生じるので、読むのがつらくなります。
私のおすすめは、もしLaravelに興味があるならば、Laravelを機能拡張するためのパッケージのOSSを読むことです。そうしたシステムはLaravelの機能の一部分だけを使っているので、比較的規模が小さく読みやすいと思います。
武田:難しく考える必要はなくて、Google 翻訳の使い方を知っていればコントリビューションはできますよ。typoの修正から始めてもいいのですから。むしろ、そうした細かな修正がすごくありがたい。なぜなら、コントリビューターたちはなるべくコードを書くことに時間を割きたいので、ドキュメントやコメントの整備まで手が回っていないことも多いためです。
他には、テストコードを追加することも良いですね。たとえば特定の機能において、その機能を実現するためのコードとテストコードがセットで存在しているとします。その後、プログラミング言語のバージョンアップで機能が増えたなど、なんらかの理由でテストケースを足さなければならないけれど、誰もテストの修正に手を付けていないことがあるんですよ。
そういった、文章のちょっとした間違いとか虫食い状態になっているテストとかが、初めてコントリビューションする方にとってはちょうどいいくらいの課題になるはずです。どんな小さな修正でも大きな意義がありますから、ぜひできることからやってみてほしいです。
取材:中薗昴、光松瞳
執筆:中薗昴
編集:光松瞳
撮影:三笠大地
関連記事
人気記事