Lesson 2: コードの読み取りと理解
クラス: 初級
所要時間: 約35分
前提知識: 初級 Lesson 1 完了済み
1. 解説
コードリーディングに Claude Code を使う意義
コードを読む作業は開発時間の大半を占める。 Claude Code は以下の場面で「読む速度」を劇的に上げる。
| 場面 | 従来 | Claude Code 活用 |
|---|---|---|
| 初めて見るファイル | 数十分〜数時間 | 数分で概要把握 |
| 複雑なアルゴリズム | コメントを手動で読む | 自然言語で説明させる |
| 関数の依存関係 | grep して手動追跡 | 一括で依存マップ作成 |
| レガシーコード | 推測しながら読む | 文脈込みで解説させる |
効果的な「読ませ方」のテクニック
bash
# 概要から詳細へ(トップダウン)
1. 「このファイルの全体的な役割を説明してください」
2. 「最も重要な関数はどれですか?」
3. 「その関数の処理を step-by-step で説明してください」
# 疑問点を深掘り(ボトムアップ)
1. 「この行の意味がわかりません」→ 行番号を指定
2. 「なぜここで try-catch が必要なのですか?」
3. 「このパターンは何という設計手法ですか?」
# 関係性を把握
1. 「この関数はどこから呼ばれていますか?」
2. 「この変数はどこで更新されますか?」
3. 「このモジュールに依存しているファイルは何ですか?」2. 実践
Step 1: 複雑なコードを用意
bash
mkdir -p ~/claude-practice/elementary/lesson2
cd ~/claude-practice/elementary/lesson2
cat > complex.js << 'EOF'
class EventEmitter {
#listeners = new Map();
on(event, listener) {
if (!this.#listeners.has(event)) {
this.#listeners.set(event, new Set());
}
this.#listeners.get(event).add(listener);
return () => this.off(event, listener);
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
return this.on(event, wrapper);
}
off(event, listener) {
const set = this.#listeners.get(event);
if (set) {
set.delete(listener);
if (set.size === 0) this.#listeners.delete(event);
}
}
emit(event, ...args) {
const set = this.#listeners.get(event);
if (!set) return false;
set.forEach(listener => {
try { listener(...args); }
catch (e) { console.error(`Listener error on '${event}':`, e); }
});
return true;
}
listenerCount(event) {
return this.#listeners.get(event)?.size ?? 0;
}
}
module.exports = EventEmitter;
EOFStep 2: トップダウンで読み解く
bash
claudecomplex.js を読んで、このクラスを説明してください。
以下の順で教えてください:
1. このクラスの目的・用途
2. 各メソッドの役割(一覧)
3. #listeners の # は何を意味するか
4. once メソッドの実装が巧みな理由Step 3: 特定の処理を深掘り
once メソッドの実装を line-by-line で説明してください。
特に「なぜ wrapper 関数を作っているのか」を詳しく解説してください。Step 4: 使用例を生成させて理解を深める
このクラスの使い方の例を3つ書いてください。
それぞれ異なるユースケースで:
1. on を使った基本的なイベント
2. once を使った一度だけのイベント
3. off を使ったイベント解除Step 5: 潜在的な問題を探させる
このコードの潜在的な問題点・改善点を指摘してください。
メモリリーク、エラーハンドリング、並行性などの観点から。3. 確認課題(Assignment)
課題 2-1: アルゴリズムの解読
bash
cat > ~/claude-practice/elementary/lesson2/algorithm.js << 'EOF'
function mystery(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = arr.filter(x => x < pivot);
const mid = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);
return [...mystery(left), ...mid, ...mystery(right)];
}
function mystery2(n, memo = {}) {
if (n in memo) return memo[n];
if (n <= 1) return n;
memo[n] = mystery2(n - 1, memo) + mystery2(n - 2, memo);
return memo[n];
}
EOFalgorithm.js を読んで、各関数が何をしているか特定してください。
アルゴリズム名、時間計算量、空間計算量も教えてください。達成条件: 両関数のアルゴリズム名・計算量が正確に特定されること
課題 2-2: 依存関係マップの作成
初級 Lesson 1 で作成した ~/claude-practice/elementary/lesson1 に移動して:
このプロジェクト内のファイル依存関係を調べてください。
どのファイルがどのファイルを require/import しているか、
矢印を使ったテキスト図で表してください。達成条件: 全ファイルの依存関係が正確にマップされていること
課題 2-3: コードの変更理由を推測
bash
cat > ~/claude-practice/elementary/lesson2/versioned.js << 'EOF'
// v2: パフォーマンス改善のため Set から Map に変更
// v1: const cache = new Set();
const cache = new Map();
function processItem(key, value) {
// v2: TTL付きキャッシュに変更
// v1: if (cache.has(key)) return cache.get(key);
const cached = cache.get(key);
if (cached && Date.now() - cached.timestamp < 60000) {
return cached.value;
}
const result = expensiveOperation(value);
cache.set(key, { value: result, timestamp: Date.now() });
return result;
}
function expensiveOperation(x) {
return x * x;
}
EOFversioned.js を読んで、v1 から v2 への変更が行われた理由と
その変更がもたらすメリット・デメリットを説明してください。達成条件: キャッシュの TTL 導入の理由とトレードオフが正確に説明されること
