Skip to main content
CleanCodeMastery

Inline Temp: Throw Away the Rough Note You Used Only Once

Learn the Inline Temp refactoring with a simple rough-paper story, TypeScript and C# examples, safe steps, IDE shortcuts, and when not to inline a variable.

23 min read Updated June 11, 2026beginner
refactoringinline tempinline variabletemporary variablesclean codecomposing methods

๐Ÿ“ The Story of the Rough Paper Note

Exam time at Saraswati Vidya Mandir. Meena, class 8, roll number 23, is solving her maths paper. Question 4 says: "Ravi buys 5 pens at Rs 10 each. What is the total?"

Meena takes her rough paper. She writes:

Total = 5 x 10 = 50

Then she turns to her answer sheet and writes: "The total is 50 rupees."

Done. The rough note did its job. Meena used it exactly one time โ€” to copy the number 50 into her answer. Now, what should she do with that rough note?

She throws it away, of course. Or she just ignores it. Nobody staples the rough paper to the answer sheet.

But imagine, for one funny minute, that Meena did staple it. Imagine her answer sheet said: "Madam, please see Rough Note 1 for the value of Total. The answer is Total rupees." Her teacher, Mrs. Khanna, would now have to flip to the rough page, find the line that says Total, read 50, hold that number in her head, flip back to the answer sheet, and put the 50 where the word Total stood. For one question, that is a small annoyance. Mrs. Khanna checks forty papers a day. If every answer made her hop to a rough page and back, she would go home with a headache and a deep dislike of roll number 23.

Now hear the uncomfortable truth: in code, we staple rough notes to the answer sheet all the time. We create a small temporary variable, give it an obvious name, use it exactly once on the very next line, and then leave it there forever. Every future reader must do Mrs. Khanna's hop: read the variable, remember its value, jump to the next line, and connect the two. One hop is cheap. A thousand hops across a big project make reading slow and tiring, and reading is what programmers do most of the day.

Figure 1: Meena's exam day โ€” the rough note is useful for one moment and a burden forever after.

Today's refactoring is the broom that sweeps away these rough notes. It is called Inline Temp, and it is the smallest, friendliest refactoring in the whole catalog โ€” the perfect place to learn the discipline of safe, baby-step code changes.

๐Ÿค” What is Inline Temp?

Inline Temp (called Inline Variable in the second edition of Martin Fowler's book Refactoring) is a very small, very simple refactoring. Here is the whole idea in one breath:

You have a temporary variable that is assigned once from a simple expression, and the name adds nothing. Replace every use of the variable with the expression itself, and delete the variable.

That is all. "Temp" is short for temporary variable โ€” a local variable that lives only inside one method. "Inline" means we push the expression directly into the place where the variable was used, the same way Meena would copy the rough work straight into the answer.

A tiny example. Before:

const basePrice = order.quantity * order.itemPrice;
return basePrice > 1000;

After:

return order.quantity * order.itemPrice > 1000;

The variable basePrice was a rough note. Its name did not explain anything that the formula order.quantity * order.itemPrice did not already say. It was used once. So we inlined it and threw the note away.

Watch what the change does to the reader's journey through the code. Before the refactoring, the reader's eyes must visit the temp, ask it what it holds, trace back to the expression, and carry the answer forward. After, the expression sits exactly where it is needed:

Figure 2: A reader interrogating the temp โ€” every read of the variable costs one extra hop to the place it was assigned.
๐Ÿ’ก

One-line memory trick: if the variable's name says nothing more than the expression itself, the variable is just a rough note โ€” inline it. But if the name genuinely explains a confusing formula, keep it. The name is the whole test.

One more important thing. Inline Temp is rarely done for its own beauty. On its own, it saves one line. Its real power is as a road-clearing refactoring. Big, useful refactorings like Extract Method and Replace Temp with Query often get blocked by little temporaries sitting in the way, like a cycle parked in the middle of a gali. Inline Temp moves the cycle so the bigger vehicles can pass.

๐Ÿ” When do we need it?

How do you know a temporary variable deserves inlining? Look for these signs:

  1. The variable is assigned exactly once and used exactly once. It is born, read one time, and never touched again. This is the classic rough note.
  2. The name repeats the expression. const total = a + b; followed by return total;. The name total tells you nothing new. Compare with const isLeapYearEdgeCase = ... โ€” that name might be doing real work, so we would keep it.
  3. The variable blocks another refactoring. You want to do Replace Temp with Query, but a trivial temp is glued between the expression and its use. Fowler's catalog says plainly that Inline Temp is almost always used in service of other refactorings, not alone.
  4. The method is tiny, but the temp makes it look bigger. A two-line method that could be one clear line.

If you audit any real, slightly messy method, the temporaries inside it usually fall into a few familiar families. Only one of those families is the target of today's broom:

Figure 3: A rough census of temps in a typical untidy method โ€” only the copied-once rough notes are Inline Temp's business.

The 40 percent slice is yours to sweep. The 25 percent slice โ€” variables reused for two unrelated jobs โ€” belongs to Split Temporary Variable, and the rest should be left alone because their names are genuinely helping.

And it connects to code smells too. A Long Method often carries a crowd of useless one-use temps that make it look even longer and scarier than it is. Sweeping them out is the first step of cleaning. Inline Temp also quietly helps prevent Duplicate Code: by freeing the expression, it lets you turn the calculation into one shared query method later, instead of letting people copy the formula around.

A small warning before we go further: this refactoring has a twin with the opposite job. Extract Variable takes a confusing expression and gives it a name. Inline Temp takes a useless name and removes it. They are inverses, like zipping and unzipping a bag. Knowing both means you can move in whichever direction makes the code clearer.

โš–๏ธ Before and after at a glance

Here is the classic shape of the change, in TypeScript. A small shop wants to know if an order qualifies for free delivery.

Before:

function qualifiesForFreeDelivery(order: Order): boolean {
  const basePrice = order.quantity * order.itemPrice;
  return basePrice > 1000;
}

After:

function qualifiesForFreeDelivery(order: Order): boolean {
  return order.quantity * order.itemPrice > 1000;
}

Same behaviour. Same result for every possible order. One less line, one less name to remember, zero hops for the reader.

Figure 4: Before, the reader must hop through the temp. After, the expression flows straight to its use.

Notice what we did not lose. We did not lose any meaning, because basePrice never carried meaning that the formula lacked. If the formula had been something cryptic like (q * p) - Math.min(q * p * 0.1, 500), then a name like discountedPrice would be earning its place, and we would keep it. The judgment is always about the name.

For the class-shaped version of this example โ€” the one Fowler himself uses โ€” picture a small Order class. The temp basePrice lives and dies inside one method, while the data it reads belongs to the whole object:

Figure 5: The Order class โ€” the temp was a private scribble inside one method, but the data it reads belongs to the object.

๐Ÿชœ Step-by-step, the safe way

Refactoring is not "change the code and pray". It is a sequence of baby steps, each so small that nothing can secretly break. Here is the safe mechanical recipe for Inline Temp. We will walk through it with this starting code:

function deliveryFee(order: Order): number {
  let distanceCharge = order.distanceKm * 6;
  return Math.max(distanceCharge, 30);
}

Step 1: Check the right-hand side for side effects. Look at the expression being assigned: order.distanceKm * 6. Does it change anything? Does it print, save, send, or count something? No โ€” it only reads and multiplies. Good. If the expression had a side effect (like cart.popItem()), inlining would be unsafe, because the expression might run a different number of times after the change. In that case, stop.

Step 2: Prove the variable is assigned only once. The simplest trick: change let to const and let the compiler check for you.

function deliveryFee(order: Order): number {
  const distanceCharge = order.distanceKm * 6; // let โ†’ const
  return Math.max(distanceCharge, 30);
}

Compile. If the compiler is happy, the variable truly has one single assignment. If the compiler shouts "cannot assign to constant", the variable is reassigned somewhere โ€” it is doing more than one job, and you must first apply Split Temporary Variable. Do not inline a multi-job variable.

Step 3: Replace one reference with the expression. Find a place where the variable is used and paste the expression there, inside parentheses if operator precedence could bite:

function deliveryFee(order: Order): number {
  const distanceCharge = order.distanceKm * 6; // now unused!
  return Math.max(order.distanceKm * 6, 30);
}

This is the honest intermediate state. The code compiles and runs the same. Most editors will now underline distanceCharge in grey โ€” "declared but never read". The tool itself is telling you the rough note is ready for the dustbin.

Step 4: Run the tests. Yes, even for this tiny change. Green? Continue.

Step 5: Delete the declaration.

function deliveryFee(order: Order): number {
  return Math.max(order.distanceKm * 6, 30);
}

Step 6: Compile and run the tests one final time. Behaviour must be exactly identical.

The whole life of a rough-note temp, from birth to dustbin, looks like this:

Figure 6: The life of a rough-note temp โ€” born, read once, made redundant, deleted.

If the variable had been used in two or three places, you would repeat Step 3 and Step 4 for each use, one at a time, before deleting the declaration. And if it is used in many places โ€” pause. Pasting the same expression many times manufactures duplicate code. The better move there is Replace Temp with Query, which we cover in the next lesson.

โš ๏ธ

Always run your tests after each baby step, not only at the end. Inline Temp looks too small to fail, and that is exactly why people get careless with it. The two classic traps are: (1) inlining an expression with a side effect, so it now runs twice, and (2) forgetting parentheses, so a + b * 2 sneaks in where (a + b) * 2 was meant. Tests catch both in seconds.

๐Ÿซ A bigger real-life example

Let us return to Meena, but now she has grown up a little and is helping her school write a small results program. Mrs. Khanna, the same teacher who checks forty papers a day, is the only user. Here is the first version. It works, but count the rough notes:

interface Subject {
  name: string;
  marks: number;
  maxMarks: number;
}
 
function totalMarks(subjects: Subject[]): number {
  const sum = subjects.reduce((acc, s) => acc + s.marks, 0);
  return sum;
}
 
function totalMaxMarks(subjects: Subject[]): number {
  const sum = subjects.reduce((acc, s) => acc + s.maxMarks, 0);
  return sum;
}
 
function resultLine(student: string, subjects: Subject[]): string {
  const total = totalMarks(subjects);
  const line = `${student} scored ${total} out of ${totalMaxMarks(subjects)}`;
  return line;
}
 
function hasDistinction(subjects: Subject[]): boolean {
  // 10 bonus marks for full attendance are not counted for distinction
  const adjustedPercent =
    ((totalMarks(subjects) - 10) / totalMaxMarks(subjects)) * 100;
  return adjustedPercent >= 75;
}

Let us inspect each temporary like a strict but fair examiner.

  • In totalMarks, the variable sum is assigned once, used once, and its name repeats what reduce already shows. Rough note. Inline it.
  • Same story for sum in totalMaxMarks. Inline it.
  • In resultLine, line is pure ceremony โ€” build a string, name it line, return it. Inline it. What about total? It is used once, and totalMarks(subjects) reads just as clearly. Inline it too.
  • In hasDistinction, the variable adjustedPercent is different. The formula behind it is genuinely tricky โ€” why minus 10? The name plus the comment carry real explanation. Keep it. This is Extract Variable territory, and inlining here would make the code worse.

After the cleanup:

function totalMarks(subjects: Subject[]): number {
  return subjects.reduce((acc, s) => acc + s.marks, 0);
}
 
function totalMaxMarks(subjects: Subject[]): number {
  return subjects.reduce((acc, s) => acc + s.maxMarks, 0);
}
 
function resultLine(student: string, subjects: Subject[]): string {
  return `${student} scored ${totalMarks(subjects)} out of ${totalMaxMarks(subjects)}`;
}
 
function hasDistinction(subjects: Subject[]): boolean {
  // 10 bonus marks for full attendance are not counted for distinction
  const adjustedPercent =
    ((totalMarks(subjects) - 10) / totalMaxMarks(subjects)) * 100;
  return adjustedPercent >= 75;
}

Four rough notes thrown away, one meaningful name kept. The file shrank, but more importantly, every remaining name now earns its line. When a reader sees a variable in this file, they can trust it is saying something important. That trust is the real product of this refactoring: in a clean file, a named variable is a signal, not noise.

What did the cleanup do to the reading effort? Count the hops โ€” every time the eyes must jump from a variable's use back to its assignment:

Figure 7: Reader hops through the results module, before and after sweeping out the four rough notes.

How do you make this keep-or-inline decision quickly? Here is the thinking path as a picture:

Figure 8: The decision path โ€” inline, keep, or choose a different refactoring.

The same judgment can be drawn as a map. Put any temp on this chart and the right move falls out:

Figure 9: Where does your temp sit? Bottom-left is the rough-note zone โ€” inline without mercy.

College corner: variable lifetimes. If you are a CSE student, here is the deeper view. Compilers think about a variable in terms of its live range โ€” the stretch of code from its definition to its last use. Meena's sum has a live range of exactly one line: defined on line 1, last used on line 2, dead immediately after. Compiler textbooks call the def-to-use link a def-use chain, and a chain of length one feeding a single use is precisely what optimising compilers eliminate automatically through copy propagation followed by dead-code elimination. In other words: by the time your TypeScript or C# becomes machine code, sum never existed anyway. This tells you two things. First, Inline Temp can never make your program faster or slower โ€” the optimiser already did it. Second, and more interesting: the refactoring exists purely for the human reader. The machine sees through rough notes effortlessly; humans do not. Clean code is the act of giving humans the same clarity the compiler computes for itself.

College corner: the memory myth. A related myth says keeping fewer variables "saves memory". For locals like these, it does not, in any way you could measure. Locals live in CPU registers or on the stack frame, both of which are recycled the instant the live range ends; a one-line temp typically never even leaves a register. Register allocators (graph-colouring or linear-scan โ€” you will meet them in a compilers course) assign these slots based on live ranges, not on how many names you typed. So never inline "to save memory", and never keep a useless temp "for performance". Both reasons are folklore. The only honest currency here is readability.

๐ŸŸฆ The same refactoring in C#

The idea is language-free. Here is the same school example in C#, the way a .NET project would write it.

Before:

public class ResultCalculator
{
    public bool QualifiesForScholarship(Student student)
    {
        var percentage = (double)student.TotalMarks / student.MaxMarks * 100;
        return percentage >= 90.0;
    }
 
    public string AdmitCardLabel(Student student)
    {
        var label = $"{student.RollNumber} - {student.Name}";
        return label;
    }
}

Step by step. First, confirm percentage and label are single-assignment. In C# you cannot declare a local as readonly, but your eyes plus the IDE can confirm there is no second assignment. Then replace each single use with the expression, and delete the declarations.

After:

public class ResultCalculator
{
    public bool QualifiesForScholarship(Student student)
    {
        return (double)student.TotalMarks / student.MaxMarks * 100 >= 90.0;
    }
 
    public string AdmitCardLabel(Student student)
    {
        return $"{student.RollNumber} - {student.Name}";
    }
}

A small C#-specific note: be careful with casts and operator precedence when inlining. The cast (double) applies only to student.TotalMarks, and that must stay true after inlining. If you are even slightly unsure, wrap the whole inlined expression in parentheses first, run tests, and remove the extra parentheses later if they are noise. Baby steps cost nothing; broken arithmetic costs an evening.

You may also ask: "Sir, should QualifiesForScholarship now be one expression-bodied method?" Yes, in modern C# you could write => (double)student.TotalMarks / student.MaxMarks * 100 >= 90.0;. That is a style polish on top of the same refactoring.

And for Python friends, the same rough note appears as:

def qualifies_for_free_delivery(order):
    base_price = order.quantity * order.item_price
    return base_price > 1000
 
# after inlining:
def qualifies_for_free_delivery(order):
    return order.quantity * order.item_price > 1000

Three languages, one idea: the name must pay rent or vacate the line.

๐Ÿ› ๏ธ IDE support

Good news: because Inline Temp is so mechanical, machines do it perfectly. You almost never need to do the find-replace by hand.

ToolHow to inline a variable
Visual StudioPut the cursor on the variable, press Ctrl+. (Quick Actions), choose Inline temporary variable
JetBrains Rider / IntelliJ IDEACursor on the variable, press Ctrl+Alt+N (Windows/Linux) or Cmd+Option+N (macOS) โ€” Inline Variable
VS CodeSelect the variable, open refactorings with Ctrl+Shift+R; availability depends on the language extension you have installed
Eclipse (Java)Cursor on the variable, press Alt+Shift+I โ€” Inline

Two practical tips. First, the IDE will warn you if the variable is assigned more than once or if inlining might change behaviour โ€” read that warning, do not click past it. Second, the IDE handles parentheses and multiple usages automatically, which removes the two classic human mistakes we discussed earlier. When a refactoring has first-class tool support, prefer the tool over hand-editing; it is both faster and safer.

๐Ÿ“Š Benefits and risks

Like every refactoring, Inline Temp is a trade. Here is the honest balance sheet:

BenefitsRisks / Costs
Removes a one-use name the reader must otherwise trackIf the name actually explained a cryptic formula, inlining deletes documentation
Makes short methods direct โ€” expression flows straight to its useInlining an expression with side effects can change how many times the effect runs
Frees the expression so Replace Temp with Query or Extract Method can proceedInlining an expensive computation used several times re-computes it each time
Less code, fewer lines, nothing to keep in syncInlining a variable used in many places pastes the expression everywhere โ€” duplicate code
Zero behaviour change when mechanics are followedOperator precedence mistakes if parentheses are forgotten during manual inlining

The single most important row is the first risk. Remember the family relationship: Inline Temp is the exact inverse of Extract Variable. Extract Variable says "this expression is confusing โ€” give it a name." Inline Temp says "this name is useless โ€” remove it." Neither is always right. A skilled developer walks both directions freely, asking only one question each time: does this name pay rent? If yes, the name stays. If no, it goes. Refactoring is not about fewer lines or more lines; it is about every line earning its place.

There is also a sibling worth knowing: Inline Method applies the same "remove the needless indirection" idea to a whole method instead of a variable.

๐Ÿงน Which smells does it cure?

Inline Temp is a small broom, so it cures small smells โ€” and clears the floor for bigger cures.

SmellHow Inline Temp helps
Long MethodSweeps out one-use temps that pad the method with hops and noise, making the true logic visible
Duplicate CodeIndirectly: by freeing the expression, it enables Replace Temp with Query, which gives the calculation one shared home
CommentsIndirectly: code that reads in a straight line needs fewer explaining comments than code full of name-hops

Be honest with yourself about direction, though. If you find a method where a huge expression is hard to read, the cure is the opposite refactoring โ€” Extract Variable. And if a temp is assigned twice for two different jobs, the cure is Split Temporary Variable. Choosing the right tool from this little family is the actual skill, and the whole family fits in one picture:

Figure 10: The temp-variable family of refactorings โ€” four tools, one shared question about where a name should live.

๐Ÿ“ฆ Quick revision box

+------------------------------------------------------------------+
|                    INLINE TEMP - REVISION CARD                   |
+------------------------------------------------------------------+
| WHAT     : Replace a temp variable with its expression; delete   |
|            the declaration. (2nd edition name: Inline Variable)  |
| WHEN     : Assigned once, used once-ish, name adds NO meaning    |
| TEST     : Does the name pay rent? No rent -> inline it          |
| INVERSE  : Extract Variable (gives a name when needed)           |
| STEPS    : 1. RHS side-effect free?   2. let -> const to prove   |
|            single assignment          3. Replace each use        |
|            4. Test after each step    5. Delete declaration      |
| DO NOT   : - Inline expensive cached values                      |
|            - Inline side-effecting expressions                   |
|            - Inline a temp used in many places (use Replace      |
|              Temp with Query instead)                            |
|            - Inline a reassigned temp (Split it first)           |
| WHY      : Clears the road for Extract Method and                |
|            Replace Temp with Query                               |
+------------------------------------------------------------------+

๐Ÿ‹๏ธ Practice exercise

Time to hold the broom yourself. Below is a small ticket-pricing module from a cinema app. It compiles and works. Your job is to judge every temporary variable: inline it, keep it, or send it to a different refactoring.

interface Show {
  basePrice: number;
  isWeekend: boolean;
  is3D: boolean;
  occupiedSeats: number;
  totalSeats: number;
}
 
function ticketPrice(show: Show): number {
  const price = show.basePrice;
  let charge = show.isWeekend ? 50 : 0;
  charge = show.is3D ? charge + 80 : charge;
  const final = price + charge;
  return final;
}
 
function isHouseFull(show: Show): boolean {
  const ratio = show.occupiedSeats / show.totalSeats;
  return ratio >= 0.95;
}
 
function popularityScore(show: Show): number {
  // weekend shows get a 1.2x boost, capped so score never crosses 100
  const boostedOccupancy = Math.min(
    (show.occupiedSeats / show.totalSeats) * (show.isWeekend ? 1.2 : 1) * 100,
    100
  );
  return boostedOccupancy;
}

Your tasks:

  1. In ticketPrice, decide the fate of price, charge, and final. Careful โ€” one of them is assigned twice. Which refactoring must visit it before Inline Temp can?
  2. In isHouseFull, should ratio be inlined or kept? Write down your one-line reason using the "does the name pay rent?" test.
  3. In popularityScore, the temp boostedOccupancy is used once. Would you inline it? Or does the name plus comment carry real meaning? There is a defensible answer on both sides โ€” write yours.
  4. Apply your decisions using your IDE's inline command, running tests (or at least re-checking sample outputs) after each change.
  5. Place each of the five temps on the quadrant chart from Figure 9. Do your placements agree with your decisions in tasks 1 to 3? If a temp lands near a boundary, write one sentence defending which side you choose.
  6. Bonus: the expression show.occupiedSeats / show.totalSeats now appears in two functions. Which refactoring from this series would give it one shared home? (Hint: it is the very next lesson.)

When you can look at any temporary variable and calmly say "you stay" or "you go" with a reason, you have mastered Inline Temp. Meena throws her rough notes away without a second thought; your code deserves the same tidy habit. Next lesson, we meet its powerful elder sibling: Replace Temp with Query.

Frequently asked questions

Is Inline Temp the opposite of some other refactoring?
Yes. It is the exact inverse of Extract Variable. Extract Variable gives a confusing expression a helpful name. Inline Temp removes a name that is not helping. The two together teach you one deep rule: keep a variable only when its name adds real meaning.
When should I NOT inline a temporary variable?
Keep the variable in three cases. One, when its name explains a cryptic formula better than the formula itself. Two, when it caches an expensive calculation that is used many times. Three, when the right-hand side has a side effect, like reading input or changing state โ€” inlining could run that side effect again.
What if the variable is used in five different places?
Then plain inlining would paste the same expression five times, which creates duplicate code. In that case do not inline. Use Replace Temp with Query instead, so all five places call one well-named method.
Does Inline Temp make my program faster?
No, and that is not its purpose. Modern compilers handle simple temporaries very well either way. Inline Temp is about readability and about clearing the road for bigger refactorings like Extract Method and Replace Temp with Query.
Why does Fowler's second edition call it Inline Variable?
It is the same technique with a more general name. The first edition said Inline Temp because the variable is usually a temporary local. The second edition uses Inline Variable to make clear the idea applies to any local variable whose name adds nothing.

Further reading

Related Lessons