現役プログラマがソースコードの追い方、読み方などをまとめてみた

ソースコードの追い方、読み方などをまとめてみた

ソースコードの追い方読み方がまるでわからない。

基本的なことを含めほとんどプログラム知識がないのに、それでもソースコードを読んで改修などをしないといけない….ということがあります。

自分のような知識なしでどうやってソースコードを追っていく、効率よく読み解けばいいのか、関連知識や読解方法を調べたりしたものをまとめてみます。

参考程度でご覧いただけると幸いです。

 

ソースコードを読めなくて困っていた状況

多少、プログラミングの知識はあるとは思いますが、今回は初めてさわる言語で「ソースコードを読んで解析し、改修をして」と言われてしまいました。。。絶望。。。

もちろん、文法を知らないプログラミング言語であり、ドキュメントの場所さえわからないなどという状況です。

そのような状況の中を変えられたらと思い、的を外したことを書きまくってもいても、とにかく記事にしてまとめておこうと思った次第です。

ソースコードを追う時に起こりうる問題

関数やクラスなんかが多くなってくると、それぞれの部分部分では読めても、全体としてどのようなことをするプログラムなのかが把握できない。

コードを上から読むと、関数などを読むことであちこちに飛び回ることになって頭が混乱する。

読んだはいいけれど、処理するデータのイメージがわかない。

このつらい状態が続くと…….

・ぼーっとしてしまう
・暇になる(暇じゃないけど)
・眠ってしまう
・泣きたくなる
などなどになる。

こういった困った事態をどうにか解決するための対策として、ソースコードを読むときに考えること、行うことを以下に書いています。

ソースコードを読むこと【コードリーディングの定義】

大前提として、「ソースコードを読むとは、どいう行為なのか」定義を一言で書いておきたい。。。

「ソースコードを読むときは、プログラムの意味(プログラムの実行結果。現実世界での効果)を、想像できること」だと思っています。

また、余談だけど、「プログラミング言語」という言葉からわかるように、プログラミングは自然言語(英語、日本語とか)にアナロジーされているかと思います。

私がプログラミング言語の入門書を初めて読んだときは、「文」という言葉が自然と出てきて、ほぼ説明が書かれていなかったのですが、プログラミングにおける「文」とは、(副作用を起こしうる)プログラムの実行単位です。

また、プログラミングにおける「式」とは、プログラムの評価単位です。「式」という言葉からわかるように、プログラミングは数学にもアナロジーされていると思います。

「文」「式」を意識しているプログラマーは、意識していないプログラマーよりも、きれいなコードを書く…….はずです。

それくらいには、大切な基本だと思っています。なぜか入門書などだとあまり説明されていない。

コードリーディングという行為に必要な知識とは

ソースコードを読むことの難しさ【ソースコードの特徴】

ソースコード(ソフトウェア)は、難しいものです。

ソースコードの難しさの特徴の一つとして、「不可視性」があります

ソースコードとは、あることを実現するために、記述されているわけですが…..

色んな状況から判断して、意思決定がされた結果として記述されています。

けれど、そのソースコードが書かれる(実装)までの背景事情(仕様、設計)は、ソースコードだけからは知ることができません。だから、難しいです。調査したり、頭の中で推測する必要が生まれます。

また、プログラム実行の状態(結果)は、常に菓子かされて目に見えるわけではありません。だから、難しいです。調査したり、あたんの中で推測する必要が生まれます。

(※この難しさを軽減するために、プログラミング言語や開発環境は進化しているし、コーディングの作法もある)

コードリーディングに必要な知識とは【コードリーディングの行為分解(別定義)】

ソースコードの難しさの特徴を踏まえて考えれば想像できると思いますが、ソースコードを読む行為は、単純にその1行のソースコードをみていればできる行為ではありません。

下記の図のように、様々な知識が必要になってきます。
(図の階層の区分けや列拳は適当です。)

 

様々なことを考えながら読む必要があります。

コードリーディングという行為の定義を別の言い方ですれば、「コードリーディング(仕様→設計→実装)過程のどこか途中からさかのぼって、内容を理解すること」になります。

自分が担当する内容次第で、求められる知識範囲や重要度はくぁってきますが、少なくとも基本文法だけを知っていればできるという行為ではありません。
(と言っておきながら、私の経験上だと、設計や実装する人は、様々な知識がないとキレイなコーディングができないですが(そして、汚いと読む人は苦労する)、読むだけなら別にさして知識がなくてもできると思っています。まさに読むことで知識を増やしていくことができますので)

 

 

なぜソースコードがわからないのか把握する

ソースコードが読めない主要因

「あーーーー!!!、読んでもソースコードわからないよ!頭に入ってこない!この部分はどのように動いているんだ!??」みたいな状態になったときは、まず、なぜソースコードがわからないのかを把握しましょう。

 

コードリーディングにつまずく段階があります。多分。。。

・文法
・概念・フレームワーク
・暗黙の作法(ルール)
・業務知識・担当機能への理解
・理解はできるけど記憶できない(読んでるうちに内容を忘れる)

上の図だと、自分はどのあたりでつまずいているのかを把握して、それを補うように対策をやってみればよいのではないでしょうか?

読みにくいソースコードの状況・条件とは

ソースコードが読めない主要因について、もう少し掘り下げてみます。(読む必要は無いです)

 

この記事を読んている人は、今までにソースコードを読めなくて困った経験がある人だと思いますが、読みにくいソースコードの条件、あるいはソースコードが読めなくて困る状況とは、どんなときか具体例を一つあげておきたいと思います。

例えば、読みにくいソースコードの例・状況としては、「決済の結果を、ユーザーが求める形に整えて、明細書に出力する」ソースコードを読むことを想像してみます。

このときの状況は下記です。

・自分の知らない文法が使用されている
・自分は上記の業務で実現したいことの知識がまるでない状態
・変数が処理の先頭で20個も定義されている。しかも、1000行に渡って散らばっていて、変数の値が色んな場所で書き換わっている。業務知識がないから、変数が表すデータが現実でなんなのかわからない
・if文で1000行近くが大きく囲まれている
for文が5つ出てくる。しかも、それぞれのfor文の階層も5階層もある

(ここまでひどいソースコードに出会ったことがないですが、)上記の状況を想像すれば、「読みにくい」と感じるはずです。

「読みにくい」と感じる理由は、プログラムを読むときに、下記の条件があるということでしょう。

・知識が足らず処理をあいまいに想像するしかない箇所が出てくる(=文法知識不)
・記憶しておくべき実行状態が多い事(=if、forなどの処理構造、変数のデータ)
・結局のところ、現実世界でやりたいこととソースコードの処理の結びつきが想像できない(=現実世界の事象と、処理構造、変数が結びつかない)

「読みにくさ」は、読むときにわからないこと(知識不足)、覚えておくべきこと(脳内メモリーによる一時的記憶)が多ければ多いほど、二次関数的に増していきます。

そして、限界を超えると、「読めない」になります。

やる気を失います。

コードリーディングをするには、わらかないこと、覚えておくべきことを減らすようにして、自分の制御範囲内に留めるのが大切だと思います。

ソースコードを読む上での心構え

まず、ソースコードを読むうえで、以下のことは大前提として常に意識しておくようにするように心掛ける。

自分にとって必要な部分に集中して読むようにする。
(完璧にすべて細かく読もうとはしない。必要に迫られたら、そのときに読めばいい)

自分の携わっているシステム、部分の役割や流れを把握しておく。

そのプロジェクトでの書き方の決まりがあればそれを頭の片隅に意識しておく。

そのソースコードを書いた人が何を思いながら書いたのかを想像しながら読む。

楽しみながら読む。

そのソースコードの行き着く先、役割はなにか。
(なんのためのソースコードなのか。扱うデータ(構造)と処理フローを意識する)

 

ソースコードの解析の分類

ソースコードを読んで追っていく方法は大きく分けて2種類に分かれる。

動的にソースコードを追う方法

デバッガなどを使って実行時の動きを追う方法。

静的にソースコードを追う方法

ソースコードそれ自体を読んで追う方法。

ソースコードを追う手順

できることなら、ソースコードを読むときの手順は以下がよい。

動的にソースコードを追う方法 → 静的にソースコードを追う方法

静的な解析は、あくまでプログラムの動作を予想することになる。
対して、動的な解析で見るのはプログラムの動作の事実。

プログラムの動きがわからない状況なら、まずは実際の動きの事実を見ておいた方が、当然にコード読解の予想の方向付けがしやすいので、早く正確にできる。

静的なソースコードの読み方

状況によって最適な方法は変わってくるのかと思いますが、いま調べてでてきた方法を書いておきます。

ドキュメントを読む・人に聞く

仕様書や設計書、コード規約など、ソースコードを読むときに役立つ資料を読む。

 

機能について知っている人がいれば聞く。

ソースコードを読むことが、プログラムの処理で現実世界でなにを実現したいのかをしることなのであれば、実現したい業務の知識について知っていれば、プログラムの処理を読解する難易度は格段に下がるということです。

充実したドキュメントと優しい人に囲まれた環境の人は活用しましょう。

メモを取る

フローチャート、クラス関係図、関数呼び出し関係図、データ構造図、コードの行番号とその該当処理など、とにかく自分が必要だと思ったことについては簡潔にメモを取っておくようにする。

 

※(追記)やはりメモを取ることは重要だと思いました。

私のようなしょぼいやつ→(´・ω・`)だと、興味のないコードを見ているときや集中していないときは眺めているだけだと頭がぼーっとして頭に入ってこない。

また、なにかの理由で作業が中断したときに内容を思い出せなくなるなんて事態も防げる。

さらには、実装完了してから1か月後とかにプロジェクトマネージャーから、内容を詳しく教えてとか言われても、忘れてしまっていてすぐに答えられないなんて事態も防げる。

読解レベルが上がるまでは、時間があればたとえそれに関する設計書がすでにあったとしても。自分の手で自分がわかりやすいように軽くでもメモを取っておく。理解しやすくなるし記憶にものこりやすい。

ツールのショートカットを使って読む

IDEやテキストエディタなど、ソースコードを読むときに自分が使っているツールのショートカットは使えるようにしておく。知っているかどうかで効率が違ってくる

ディレクトリ構造を読む

どういう方針でディレクトリが分割されているのかを見て把握する。
それぞれのモジュールがどういう関係があるのか確かめる。
そのプログラムがどのように分割され組み立てられ作られているのかを概要を知る。

ファイル構成を読む

ファイル名を含め、ファイルの中に入っている関数(名)も合わせて、どういう方針でファイルが分割されているのかを見る。

システムの各機能の流れを書いてみる

自分が調べたい箇所に関するシステムの全体の流れについて、図なりにして書いてみる。

略語の調査

わかりにくい略語があればリストアップしておいて早めに調べる。
英語だと単語の頭文字をとったり、母音をなくすとかが多い。
また、対象プログラムの分野で有名な略語は説明なしで使われている。

データ構造を知る

プログラムは、あくまでデータを処理するためにある。(らしい)
なので、どんなデータが入出力されるか、どう変化していくのかに着目しておくようにする。

Javaなどオブジェクト指向言語のソースコードの読み方

変数(オブジェクト)のスコープ(可視範囲)を意識すること。
オブジェクト指向言語のコードは「上から下に」読むものではない。(らしい)
 
私はコードの一行一行を読むときは「上から下に」読むのですが、処理単位で読むときは「多方向に」関係をイメージをしています。
 
(たしか)オブジェクトは関連した処理とデータをまとめた存在であり、オブジェクト指向言語は各オブジェクト同士の相互影響で成り立つ世界です。
 
日本語のような自然言語みたいに、上から下のように順々に読んでいくものだという認識がおかしくて(最初のころはこの認識だった)、ネットワークのように張り巡らせた状態の言語だと思って読むのがラクです。

プログラミング言語やフレームワークの設計パターンを知っておく

こういう優れた、各プログラム言語でよく使わられる定石や公式といったものを知識として蓄えておくようにしていく。

 

動的なソースコードの読み方

動的にソースコードを解析してくれるデバッガツールを使いましょう。

プログラムを動かしてみる

実際に動かしてみて、どんな動きをするのかを見てみる。

 

メジャーなプログラミング言語なら、IDEなどの開発環境には、たいていはデバッグ実行・ステップ実行ができるようになっていると思います。

デバッグツール(デバッガ)の使い方を知る

デバッグツールの使い方を最低限知っておくとよいです。

 

極端に言うと、開発ツールの機能のうち、最も初心者が知るべき機能だと思います。

また、極端に言うと、ほとんど文法を知らないプログラミング言語で、フレームワーク知識のない状態でも、一行一行の処理をデバッグで止めて、その都度データの状態を確認することができるなら……

朝から晩までひたすらコードをデバッグし続ければ、どのような記述のときに、どんな処理がされるのか、ある程度推測は出来るようになると思います。

なので、デバッグは必須知識です。
デバッグはGoogle検索と並ぶプログラミングの先生です。

好きに操作して動かしてみる(推測の確認)

デバッグをするときは、「ある処理(行)のときに・データ状態はこうなっているはず」という自分の推測を確かめる、仮説検証の行為だと思っています。

 

自分の推測と実際の処理動作が正しいかどうか。
推測と実際のズレはどこにあるか。

それを考えながらやっていくのがおススメです。

処理の途中で値を変えてみたら、動作にどんな影響を与えるかを見ながら動かしていくとか。(デバッグ中に値を変えられる機能です)

自分の着目したタイミングでのみコードを見たいから、条件付けして止めてみたり。(特定の条件のときのみ処理を止める機能です)

詳しくはないですが、フィルターを掛けてみたり、REPLで確認したり、インスペクトしたり、監視したり……

自分の開発環境でできるデバッグ機能を使って、好きに操作していきましょう!

ソースコードを読むということ

ソースコードを読むということは、誰にとっても瞬きでできるようなことではなく、多分誰にとっても多かれ少なかれ手間がかかる者なのだと感じました。

コメントを残す