

プログラマー初心者です。  
初歩的な質問で申し訳ないのですが、よくプログラミングの上達法として、「人の書いたソースを読むと良い」と聞きます。  
実際に読んでいますが、ソースコードを追っても、途中からサッパリです。  
（PHPフレームワークで作られたアプリケーションのソース等を読んでます。）

ベテランのエンジニアの方で、ビギナー時代にこの点をどのように克服してきたのか、何か良いヒントを頂けないでしょうか。  
個人的な見解ですが、人が書いたソースコードが読めれば、様々な場面でのプログラミングの技術を蓄積できると思います。  
これ以外にも、何か上達の方法としてオススメな方法等あれば、教えていただきたいです。  
情報お待ちしております。


CC BY-SA 4.0
2018-11-06T16:33:50.230
50021
2018-11-07T11:41:29.353
30871
question
php
人が書いたプログラムってどう読む？


私は、以下のような要素を順に気をつけています。

# 1\. README等のドキュメントを探す

まず

  * READMEや、簡単なIntroductionドキュメント
  * エントリポイント等の一番基本になるコードのコメント

などから、一般的な説明が書かれていないか確認しておきましょう。  
残されているドキュメントには、基本的な使い方や、  
特に注意喚起したいと開発者が考えた点が書かれているものです。

傾向としてはその後の作業の助けになることが多いです。  
他にはコード規約なども読んでおくと、そのソースを読む助けになるかもしれません。

# 2\. ビルド設定等から、利用しているライブラリを知りましょう

ビルドスクリプトやパッケージマネージャの設定(例: PHPならcomposer.json)を探しましょう。

ビルドスクリプトなどを読むことで、使われているライブラリやフレームワークを理解できることがあります。  
その時はリファレンスへのリンクなどを手元に集約して、参照しやすい状態にしましょう。  
それらの一般的な使い方の書かれた、READMEやIntroduction眺めるのも助けになります。  
簡単なサンプルコードを探して、役割を理解しておきましょう。

クラス図などのアーキテクチャに関するドキュメントを見かけたら、ある程度眺めて構造を理解しておきましょう。

# 3\. 実行できるようにしましょう

次に対象のコードはそもそも何をするコードなのか、実行して大まかに知っておきましょう。  
動作のことを知らないでコードを読むのは、足がかりになる部分がなく大変になることが多いです。

関連することとして、コードをビルドして動かせる状態にするのはとても大事です。  
コードを読むことでコードを知るのをコールドリーディング。  
コードを動かしてコードを知るのをホットリーディングといいます。  
ホットリーディングは、コールドリーディングよりも簡単なことが多いです。  
なにせ該当部分を動かしてしまえば、動作は一発で理解できますよね。

気になる部分のコードを、コピー＆ペーストして必要な変数などを適当に埋めて、動かしてみるのも有効です。

またもし、きれいに保守されているコードであれば、自動テストコードがあるかもしれません。  
これらのテストコードを動かせる状態にするのも重要です。  
テストを動作させる方法をドキュメントや、そのフレームワークの一般のテストの書き方などから知りましょう。

ここを動かせれば、ホットリーディングしたい時に、新しい自動テストを書くという手段が使えるようになります。  
自動テストコードは、小さなサンプルコードの集積でもあります。  
そのためここから、それぞれの関数やクラスの使い方を理解することができます。

# 4\. ディレクトリ構造/プロジェクト構成を理解しましょう

それからソースリポジトリの、大まかなディレクトリ構造/プロジェクト構成を理解しておきましょう。

ソースファイルがここにあって、参照する設定ファイル群はここにある。  
ソースファイルは、エントリポイントになるコードがここにあって、ライブラリモジュールはここにある。  
xxxに関するライブラリモジュールはこのディレクトリ、yyyに関するライブラリモジュールは、このディレクトリ。

……といった具合です。

UNIX系OSを使っている時は、ディレクトリの再帰的な構造を表示する `tree` コマンドが助けになるかもしれません。  
ディレクトリ名はそのまま、ある程度モジュールの構造を反映していることが多いです。

もし対象のソースコードが使っているフレームワークが、一般にプロジェクトテンプレートを提供しているなら  
自分で新しくプロジェクトをテンプレートから作成し、 まっさらな状態で `tree` を見ておきます。  
そして、対象のソースコードと、まっさらな状態で、どのように `tree` が違うのか、差分を理解しましょう。  
その差分は、対象のソースコードで増やされた物です。これで独自の実装が入っている部分がわかります。

# 5\. エントリポイントを列挙しておきましょう

実質的なエントリポイント(実行の開始点)を列挙しておきましょう。  
コマンドラインツールでは、どこかのソースファイルや、いわゆるmain関数などがエントリポイントになっている傾向があります。  
一方でWebフレームワークでは、プログラムのエントリポイント(動作の開始点)になる所は、  
実質的にControllerのアクションになることが多いので非常に沢山のエントリポイントがあるかもしれません。

Webフレームワークの場合、アクションルーティングの設定値を確認することでエントリポイントを列挙できる場合もあります。  
またそのためのコマンドが準備される場合もあります。  
使っているフレームワークのエンドポイント管理について一般知識を用いて調べましょう。

# 6\. 「気になること」を決めましょう

エントリポイントの中で、自分が今気にしてみたいことを決めてみましょう。  
トピックを1つに限ることで、読むべきソースが絞られます。  
大量にあるコードで混乱するのを避けるために大事です。

エントリポイントそれぞれが何をやっているのか、名前やURLから大まかな役割を推測しましょう。  
特にWebフレームワークで作られたソースコードの場合、  
動作しているプログラムで、どういったURLが、何の画面を出すのに使われているか、という知識が役立つでしょう。  
突き合わせれば、どのエントリポイントが何の役割を担っているかわかるからです。

# 7\. エントリポイントの1つを読んでみましょう

エントリポイントのうちの、決めた1つを読んでみましょう。

このとき、呼び出している関数などの詳細には潜らずに  
やっている関数の名前や、コードの構造から  
「AをやってBをやってCをやってる」というような  
「やってることベース」で理解してみましょう。

ただ各モジュールに潜らずに表面を撫でて  
大まかな「あるモジュールの実行が生じる条件」への理解を得るのを目標にします。

これにはコールドリーディングが必要になる傾向があります。諦めずに頑張ってみてください。

# 7\. 気になることに関連していそうな中で、一番簡単そうなソースファイルを1つだけ局所的に読んでみましょう

エントリポイントで呼び出されていたモジュールに関連するソースをある程度調べます。  
そして小さく、読みくだせそうなソースコードに的を絞って、そこを理解してみましょう。  
理解できているソースファイルが1つ増えると、そこを足がかりにして連鎖的に理解出来る傾向があります。

簡単であると言える基準としては

  1. 他から呼ばれる側のコードであり、別のモジュールを(あまり)呼び出していないこと
  2. いかにも文法上複雑そうなテクニックは、特に使われていないこと
  3. ファイルとして単に文字数が少ないこと

などがあります。

読むときにはコールドリーディングも、ホットリーディングも活用して、どんな働きを持っているのか言葉にしてみましょう。  
得た知識がただしいか検証するために、ソースを書き換えてみて、狙った違う挙動を実現してみましょう。  
得られた結果は思ったとおりだったでしょうか。それならOKです。違った場合は、理由を考えてみましょう。  
テストコードを新しく足すのも良い選択です。値を入れて、狙った動作をするか確認できます。

ここは1つ理解できたら、次の1つを探して徐々に広げていきましょう。

# 8\. 図を起こしましょう

いくらかソースを読み込んでくると、徐々に知識が溢れてきます。  
それらを頭の中に放置していると、だんだんわからなくなりますので  
図面を起こして、各ソースコードの呼び出し関係や、利用の仕方の関係を自分なりにまとめてみましょう。  
紙の上に、雑に書くのが有用です。プリンタ用紙などを束にして準備して雑に使うのがいいでしょう。

ここまでくると、ある程度1つのエントリポイントについて理解できた状態になるはずです。

# 9\. 繰り返します。

1つエントリポイントを理解できたら、これを繰り替えし行いましょう。  
そうやって理解できる範囲が広がったら、これももっと大域的な図を起こします。  
これで全体を理解出来る状態になるでしょう。

ただし全体を理解し尽くさなくても目的達成出来る場合が多いので、ある程度で止めてOKです  
ここまできたら自分の足し込みたいプログラムを書き込んで目的を達成しましょう。

# X. その他トピック

  * リポジトリのログ(`git log`など)は役立つ情報になることがあります。特にプロジェクト新規開始時の、スケルトンに近い状態のソースに戻して、順番に見ていくことは、構造を理解する上で非常に助けになります
  * IDEやデバッガを持つ言語では、コードをステップ実行するのも非常に助けになります。特にエントリポイントの大まかな挙動を理解する時には効果的です。
  * ソースコードから、部分的にコードを、コメントアウト/削除するのも有効な手段です。これをやるとその部分がやっていることがどんな影響を与えているのか理解できます
  * 特に子クラスを読む前に親クラスの仕様をよく知っておきましょう。
  * ある親クラスに対して、その子クラスにはどんなものがあるのか、列挙しておくと助けになる場合があります。
  * コールドリーディングを上手くするには、「サンプルコードを頭の中だけで実行する」という訓練が有効です。眼で追って、プログラムを"脳内実行"します。プログラムを実行したくなるのをぐっと我慢して、頭の中で1手順ずつ、完全に動作を再現してみるのです。


CC BY-SA 4.0
2018-11-07T00:21:18.710
50030
2018-11-07T00:21:18.710
30827
50021
answer


@rugamaga さんの回答が非常に素晴らしく、とても参考になります。  
蛇足のような気もしますが、文系プログラマの視点からもう少し次元の低い回答を書きます。

確かによくプログラミングの上達法として「人の書いたソースを読むと良い」と聞きますが、これは下記の条件を満たす **初～中級者向け**
の学習法と感じています。

  * プログラムの構文が大体理解できる
  * 条件分岐や再帰処理など、処理の流れを理解できる 
    * 「そんなの誰でもできるだろう」と思う方もいるでしょうが、それができない初学者は存在します
  * 「ほげほげ機能の実装方法を知りたい」「ふがふがフレームワークのサンプルコードが欲しい」など **目的や目標を定めて** ソースリーディングできる

目的やスキルがない状態で他人のソースを学習用に読むのは、下記のような例で挫折する確率が上がるのではないかと予想します。  
根拠は実体験です。

  * 複数ファイルで使う広域変数がどこにあるか分からない
  * 呼び出している関数がフレームワーク由来か独自のものか分からない
  * そもそも1つの関数が何をしているのか分からない
  * 続きは明日にしよう→昨日何を理解したか分からない

真面目な初学者は「人の書いたソースを読むと良い」と聞いて黙読するものですが、それは学習効率が高くありません。  
「人の書いたソースを **改造して遊ぶ** と良い」と言い換えた方が効率的な学習につながるでしょう。  
改造する内容は高望みせず、まずはびっくりするほど簡単で良いです。  
「画面にアイコンを追加する」「リストの項目を別のものに置き換える」程度の独力ですぐにできそうな改造をするだけで、少なくとも下記の効果が見込めます。

  * 他人のコードをチェックアウト、ビルドする手順を学べる 
    * 案外フレームワークやライブラリの導入に苦労して学べることも多かったりします
  * 他人のコードに自分のコードを追加することで、コーディングの癖を自覚できる
  * コードを書き換えて動かなくなることでデバッグ経験を積める
  * 改造に必要な関数の中身を **本気で** 読み始める

楽しく改造する過程で、もしも「あれ？これ元ソースのバグじゃね？」なんて箇所を改修してプルリクできるようになれば、気分は上級者です。  
ここまで到達すると、日常の開発も楽しくなるかもしれませんね。

> これ以外にも、何か上達の方法としてオススメな方法

  * プログラム学習書を一冊写経する 
    * 読むのではなく、サンプルコードをとにかく写経して動かす作業を繰り返します。  
本当の初心者には写経が重要です。コードや説明が理解できなくてもとにかく写経して動かしましょう。  
分からないことは読み返しても分かりません。改造して遊んだり次の章を読み進めるとある日パッと理解できたりします。

  * プログラミング動画を見て最後まで写経する 
    * 良い時代です。  
動画を見ながらインストールやコード追加をすると、動画の通りにやれば良いのでつまづく可能性が減ります。  
途中で「全部わかった」「もういいや」となるかもしれませんが、学習書も動画も最後までやり遂げることは大事です。  
完成品が手元にあると達成感がありますし、最後までやり遂げた実績は自身の自信につながります。

私の経験から来る初学者へのヒントは以上です。  
ヒントでなくアドバイスはただ一つです。

**毎日** IDEを立ち上げて、 **1行でも** いいからコーディングすること。


CC BY-SA 4.0
2018-11-07T01:00:11.320
50031
2018-11-07T11:41:29.353
2018-11-07T11:41:29.353
9820
9820
50021
answer


他人のコードを読んで何を読み取るのかその目的にもよるかと思いますが、いきなり全体の動きを把握するのは(慣れてる人でも)なかなか難しいと思います。

とっかかりとしてはコーディングスタイル(インデントや変数の命名規則)辺りを参考にしてみては如何でしょうか。読み進めるうちに知らない関数などが出てきたら、まずは
**ドキュメントを調べてみる** のも重要だと思います。


CC BY-SA 4.0
2018-11-07T01:11:10.727
50032
2018-11-07T01:11:10.727
3060
50021
answer


公開されているコーディングスタイルガイドのコードを参照すると、プログラミングコードを記述する上での注意点や陥りやすい問題を理解するのに役立ちます。

特定のプロジェクトチームや企業におけるコーディング規約は非常にまずい規約(過去のビジネス上のミスに起因するトラウマ的な規則や古すぎて意味の無いもの)も存在します。

わかりづらいコードを見てみるのも全く無駄ではなく、わかりやすい部分とわかりづらい部分、その理由を考えてみるのも上達するうえでは重要です。

そういった問題の多いプログラムコードを解説した本もいくつか過去に購入して読みました。


CC BY-SA 4.0
2018-11-07T01:17:07.263
50034
2018-11-07T01:17:07.263
22888
50021
answer