# Split Temporary Variable

> Give each distinct purpose its own variable when one local is reassigned to hold unrelated intermediate values.

- kind: technique
- category: composing-methods
- aliases: Split Variable
- canonical: https://aipatterns.dev/refactoring/techniques/split-temporary-variable
- inspired-by: https://refactoring.guru/split-temporary-variable

## Problem

One local variable is reused for several unrelated values: first a count, later a percentage, later a label. Each reader has to track which meaning is live at which line, and extracting any fragment drags the shared variable along.

## Solution

**Declare a separate, well-named `const` for each purpose.** Loop accumulators (`sum += x`) and collecting variables are the exception: they hold one meaning that grows.

## Before

```ts
function summarizeFunnel(events: AnalyticsEvent[]): string {
  let temp = events.filter((e) => e.type === "visit").length;
  const visits = temp;

  temp = events.filter((e) => e.type === "signup").length;
  const signupRate = visits === 0 ? 0 : temp / visits;

  temp = events.filter((e) => e.type === "purchase").length;
  const purchaseRate = visits === 0 ? 0 : temp / visits;

  return `visits=${visits} signup=${(signupRate * 100).toFixed(1)}% purchase=${(purchaseRate * 100).toFixed(1)}%`;
}
```

## After

```ts
function summarizeFunnel(events: AnalyticsEvent[]): string {
  const visits = events.filter((e) => e.type === "visit").length;
  const signups = events.filter((e) => e.type === "signup").length;
  const purchases = events.filter((e) => e.type === "purchase").length;

  const signupRate = visits === 0 ? 0 : signups / visits;
  const purchaseRate = visits === 0 ? 0 : purchases / visits;

  return `visits=${visits} signup=${(signupRate * 100).toFixed(1)}% purchase=${(purchaseRate * 100).toFixed(1)}%`;
}
```

## Why

- Each name states one meaning for its whole lifetime.
- `const` lets the compiler reject accidental reassignment.
- Fragments become independent, so [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md) and [Replace Temp with Query](https://aipatterns.dev/refactoring/techniques/replace-temp-with-query.md) apply cleanly.

## Steps

1. Find the first assignment of the reused variable. Rename the variable at that assignment and its reads up to the next assignment. Declare it `const`.
2. Compile and run the tests.
3. At the next assignment, declare a new `const` with a name for that purpose and update the reads that follow it.
4. Repeat until each assignment has its own variable. Delete the original declaration if nothing uses it.

## Watch out

- Don't split accumulators or loop counters whose reassignments all serve one meaning (`total += line.amount`).
- Check closures. A callback created earlier may capture the original variable and observe later values; splitting changes what it sees.
- If the variable is a function parameter, apply [Remove Assignments to Parameters](https://aipatterns.dev/refactoring/techniques/remove-assignments-to-parameters.md) instead.
- There is no useful inverse. Merging unrelated values into one variable is the smell itself.

## Related

- Helps with [Long Method](https://aipatterns.dev/refactoring/smells/long-method.md).
- Prepares for [Replace Temp with Query](https://aipatterns.dev/refactoring/techniques/replace-temp-with-query.md) and [Extract Method](https://aipatterns.dev/refactoring/techniques/extract-method.md).
- [Remove Assignments to Parameters](https://aipatterns.dev/refactoring/techniques/remove-assignments-to-parameters.md) is the same fix for parameters.

## Agent checklist

- [ ] Every reassignment served a different purpose; accumulators were left alone.
- [ ] Each new variable is `const` and named for its meaning.
- [ ] No closure captured the old variable and relied on later values.
- [ ] Tests pass.
