Skip to content

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;
EOF

Step 2: トップダウンで読み解く

bash
claude
complex.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];
}
EOF
algorithm.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;
}
EOF
versioned.js を読んで、v1 から v2 への変更が行われた理由と
その変更がもたらすメリット・デメリットを説明してください。

達成条件: キャッシュの TTL 導入の理由とトレードオフが正確に説明されること


自己チェックリスト


次の型

Lesson 3: 単純なバグのデバッグ →

Claude Code Dojo