PHPで書かれたコードの読み方に興味がある方向けのLT

inoco氏:それでは始めたいと思います。「ちょこっとラクするPHPコード読解術」というLTをします。井上と申します。ホワイトプラスという会社でエンジニアリングマネージャーをやっています。

今回のLTですが、PHPで書かれたコードの読み方に興味がある方向けのトークになっていて、おそらく、主に初心者の方向けになるかなと思っています。

(スライドを示して)アジェンダはこんな感じです。前提ですが、私の場合、静的解析に興味があって、その仕様を理解する目的でコードを読むことが多いです。そういった背景がある中での経験に基づいて話すので、若干知識や考え方が偏っている可能性がありますが、そのあたりは差し引いて聞いてもらえればと思います。IDEは基本「PhpStorm」を使っているので、そういった前提での話になります。

本日伝えたいことですが、「あなたのコードの読み方を教えてください」ということです。「こんな工夫をしているよ」というようなことを、ぜひ「X」にポストしてみてもらえるとうれしいです。なんですが、その前に私のやり方も紹介したいと思っています。

考えることに集中するために、“機械に委譲する”

初めに結論から言うと、「『Xdebug』を活用しましょう」ということになります。

それでは、背景から説明したいと思います。(スライドを示して)まず解決したい課題です。コードが込み入ってくると迷子になりやすいということがあって、覚えることと考えることを同時にやるのは負担が大きいです。

なので、覚えることを減らして、考えることに集中したいです。「覚える」と言っているのは何をかというと、例えば変数の中身や式がどう評価されるのかというような話です。

こういった課題に対していくつかやっていることがあります。まとめると、目的を絞って明確にすること、メモをしながら読むこと、問題をシンプルにすること、機械に委譲することです。そして、機械に委譲するというのが今日話したいスコープになってきます。

(スライドを示して)それ以外も簡単にまとめておくと、まず目的を絞ると言ったのですが、その目的自体を決めづらかったりすることもあるかなと思っています。自分の場合は、オープンソースのissueを漁ってみて、issueを起点に読み始めることをしています。

例えば、バグがあって、「こんなふうに挙動がおかしいよ」みたいなissueがあったら、その仕組みを理解します。どんなふうにどんなバグが起きていて、どう直せばいいのかを目的にしてコードを読んでいます。

コードを読む中での思考の過程をメモするのですが、それはコードの中に書きます。なぜかというと、コードの外に書こうとすると、メモと該当箇所の紐づけが煩わしいからです。

コードと紐づけて考えなくていいような確認ごとなどは箇条書きにして……。どこでもいいのですが、どこかにメモしておきます。

簡単化するというのは、観察したい処理をまずはシンプルな処理で挙動を確認して、だんだん複雑にすることで慣れていくということをやっています。

機械に委譲するというのが、本日のスコープになります。

Xdebugのステップ実行で1行ずつ着実にコードを読む

というわけで、Xdebugの活用方法について話していきたいと思っています。まず、コードを読む時に、静的にコードを読むことだけではなくて、動かしてみるのがいいだろうと考えています。

簡単なものであれば、例えばvar_dumpとかをすればいいかもしれないのですが、複雑になってくると大変なので、Xdebugを活用するとよさそうだと思っています。

1つ目の便利ポイントですが、ステップ実行です。1行ずつ、読み間違うことなく進められることが良いです。

(スライドを示して)例えば「Laravel」の起動処理を知りたい、理解したいと思った時は、起動のindex.phpを読みにいきます。(スライドを示して)すると、赤字の部分は型がついていなくて、IDEでジャンプしようとしてもジャンプができなくて読みにくくなっています。

例えば、前の処理を読んで、クラスを特定して、そのクラスの中からメソッドを探してみたいな手間(が発生する)とか。あるいは、そこで脳内メモリが消費されることが起きます。

一方で、ステップ実行をすると1行ずつ実行できます。例えば$app->makeのメソッドの中に入って、1行ずつ見ていくことができて、実際の処理順に従ってメソッドの中を読み進めることができます。

(スライドを示して)この例のように、Applicationクラスのmakeメソッドが処理されるのを目視確認できるということがわかりやすいです。

(スライドを示して)ここでもメソッドを呼んでいるので、さらにこの中に入って。例えばif文があると、メソッドを解釈したり変数を覚えておいたりプロパティを覚えておいたりする必要が出てきて、また脳内メモリを食っちゃいます。

ですが、ステップ実行すると、実際にtrueなのかfalseなのかを目で見て確認できるので、ひとまず読み流したい時に簡単にできるのが良いところです。

処理が複雑になってくると「もうどこから手をつければいいのか」という気分になって、手が止まったり思考が止まったり疲れちゃったりすると思うのですが、ステップ実行であれば1行ずつ着実に見ていけるので、気持ちが軽くなると言えます。

変数を覚えないことで脳内メモリの消費を抑える

2つ目の便利ポイントは、変数の中身が見られるということで、ここでも脳内メモリの消費を抑えられます。  

(スライドを示して)右下の赤い枠で囲った部分に変数がずらりと並んでいます。

これをズームして、矢印のアイコンを押すとさらに展開されて、多数の変数が出現してきます。というわけで、とてもじゃないが覚えきれないです。

そもそも全部覚える必要もないのですが、処理が込み入ってくるといくつかの変数を覚えておいたりしないといけなくなってきます。それはそれで大変なので、機械に任せられるところは任せてしまいたいという話です。

スタックトレースの活用で処理の過程も覚えない

3つ目の便利ポイントは、スタックトレースです。これがあると処理経路に気づけたり、処理の過程を覚える必要がなくて、これも省メモリになります。

またLaravel関連の例で、Eloquentのscopeという機能があると思うのですが、あれがどういうふうにして呼び出されるのかを知りたいと思った時に、コードを読もうにもどこから読めばいいかわからないという状態に陥ります。

そんな時でも、scopeメソッドの中にブレイクポイントを仕掛けて処理を実行します。

そうすると、左下の赤枠で囲った部分がスタックトレースですが、どんなふうにしてORMのscopeTitleというメソッドまでたどり着いたのかを、1行1行追いかけることができます。

(スライドを示して)ここですが、1個遡ると、scopeTitleというメソッドの名前を組み立てていることが読み取れたり、さらに遡ると、Post::titleという呼び出しからマジックメソッドが取り出されていることも見てとれます。

スタックトレースからのジャンプでコードを簡単に追いかけられる

4つ目の便利ポイントは、スタックトレースからのジャンプです。(スライドを示して)例えば、先ほど見たスタックトレースの「click」と書いている部分をクリックします。

すると、scopeTitle()メソッドに飛んでくるので、コードを簡単に追いかけることができる仕組みになっています。

また、スタックトレースから該当箇所にジャンプして、さらにそこに広がっている変数も全部見ることができます。なので、見たいところに移動して、そこの変数を確認するということが、すでに通り過ぎた処理においてもできるのが便利です。

おまけのTips

(スライドを示して)Xdebugの話は以上で、おまけのTipsです。私は静的解析を読むことが多かったので、1個目が、Xdebugを使って静的解析を読む時は、基本(的に)並列処理ができることが多いですが、それをoffにしないと動きがおかしくなります。

Xdebug以外にも人間の能力を委譲すべきツールがいくつかあるので、こういうものを活用すると、より楽に、ちょこっと楽にコードを読むことができます。

ツールを使うことで楽にできるのですが、そうはいっても、前提知識が多いに越したことはないので。例えばマジックメソッドを知らないと挙動がどうなるのかがわかりにくいので、前提知識は多いに越したことはないでしょうという話です。

コードは読むものではなくて、機械に読ませるもの

まとめます。コードは読むものではなくて、機械に読ませるものです。その中で、Xdebugはすごく役に立つので、ぜひぜひ活用してみるといいのではないでしょうかというお話でした。

以上となります。ご清聴ありがとうございました。