Learning Goals 3 min
By the end of this lesson you will be able to:
- Define refactor in your own words — and explain why "doesn't change what the program does" is the most important part.
- Spot a repeated chunk in a long script (three or more copies of the same blocks) and extract it into a new My Block.
- Read a before-and-after pair and judge which is easier to debug, easier to change, and easier for a teammate to understand.
Warm-Up — Priya's hop-and-meow monster 7 min
Priya wants the cat to hop and meow four times in a row. She built this:
when flag clicked
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
It runs. The cat hops and meows four times. So why does this stack make experienced Scratchers wince?
Reveal the answer
The same three-block chunk — change y by (40), play sound (Meow v) until done, change y by (−40) — is copy-pasted four times. If Priya later wants the cat to hop higher (say, 60), she has to edit it in four places. If she misses one, the cat will hop unevenly. If she wants five hops instead of four, she has to copy-paste a fifth chunk. Every change is four changes.
Today you learn to fix this kind of mess by refactoring: pulling the repeated chunk out into a single My Block and calling it from a clean little loop.
New Concept — refactoring 15 min
Real programmers spend a surprising amount of time not writing new code, but rearranging code they've already written. There's a word for it.
Refactor — the careful definition
Refactor means: change the shape of code so it's easier to read or change, without changing what it does. After a refactor, the program behaves identically. The stage looks the same. The sprite acts the same. Only the inside is tidier.
That "without changing what it does" rule is sacred. If your hop-and-meow runs four times before, it must run four times after. If you accidentally broke that, you didn't refactor — you introduced a bug.
The rule of three
Here's a guideline working programmers use:
- Once — just write it. Don't make a function yet.
- Twice — start to feel suspicious. Maybe a My Block.
- Three times — extract it now. You've earned the My Block.
Priya's chunk repeats four times. Past the threshold. Time to refactor.
The refactor recipe
Three steps. Always the same three steps.
- Spot the chunk. Find the smallest group of blocks that repeats. Priya's: three blocks (up, meow, down).
- Extract it. Make a Block with a descriptive name — hop and meow — and paste the chunk into the define stack.
- Replace the copies. Delete all four copies in the original script and call the new block instead — usually from inside a repeat.
Before and after
Here's Priya's mess:
when flag clicked
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
change y by (40)
play sound (Meow v) until done
change y by (-40)
And here's the refactored version — same behaviour, way fewer blocks:
define hop and meow
change y by (40)
play sound (Meow v) until done
change y by (-40)
when flag clicked
repeat (4)
hop and meow
end
What you gained
- Readability. "Four hops and meows" reads like English. The mess didn't.
- Edit-once. Want the hop higher? Edit one number in one place.
- Self-documenting. The name hop and meow tells the reader what's going on. Comments help, but well-named My Blocks help more.
- Reuse. Now any other script in the project can call hop and meow too. Free reuse.
Worked Example — refactor Priya's stack 12 min
Open Priya's project (or just rebuild the warm-up stack above). Eight steps to a clean script.
Step 1 — Click the flag and confirm the behaviour
The cat hops and meows four times. Mentally photograph this — after the refactor, you'll compare.
Step 2 — Spot the chunk
Eyes on the stack. Three blocks — up, meow, down — appear four times. That's your chunk.
Step 3 — Make a Block
My Blocks → Make a Block. Name it hop and meow. No inputs needed. Click OK.
Step 4 — Move the chunk into the define
Grab the first change y by (40) in the original script (the very first one). Drag the chunk of three blocks off the stack — they come away together. Snap them under define hop and meow.
Step 5 — Delete the other three copies
The original script still has three copies of the chunk dangling. Right-click → Delete Blocks on the first block of each copy. The script shrinks dramatically. The hat now has nothing under it.
Step 6 — Add a repeat with the new caller
From Control: repeat (10). Snap under when ⚑ clicked. Change the 10 to 4. From My Blocks: drag hop and meow into the repeat C.
Step 7 — Click the flag
Same behaviour. Four hops, four meows. The Stage doesn't know anything changed.
Step 8 — Now feel the win
Change the 4 to 7. Click the flag. Seven hops. One number. In the old code, this would have meant copy-pasting the chunk three more times.
The full before-and-after
define hop and meow
change y by (40)
play sound (Meow v) until done
change y by (-40)
when flag clicked
repeat (4)
hop and meow
end
What you just did: the single most common cleanup move in all of programming. Every senior developer in the world does some version of this every day. It has a name (Extract Method in Java, Extract Function in JavaScript) and a whole book by Martin Fowler about it. You just did it in Scratch.
Try It Yourself — three refactor drills 15 min
Goal: Refactor this nine-block stack into a clean loop. Spot the repeated chunk first — it's three blocks long and appears three times.
when flag clicked
say [Hi!] for (0.5) seconds
change x by (50)
wait (0.5) seconds
say [Hi!] for (0.5) seconds
change x by (50)
wait (0.5) seconds
say [Hi!] for (0.5) seconds
change x by (50)
wait (0.5) seconds
define greet and step
say [Hi!] for (0.5) seconds
change x by (50)
wait (0.5) seconds
when flag clicked
repeat (3)
greet and step
end
Think: What if the original had said "Hi!" twice and "Bye!" once? Could you still extract one block? (Hint: no — they're not the same chunk.)
Goal: A game's startup script has 8 blocks that always run when the flag is clicked: reset score, move to start, set rotation style, point in direction 90, set size to 100, switch costume to default, show, clear graphic effects. Extract them all into one well-named My Block, then call it from the flag hat.
define set up cat
set [score v] to (0)
go to x: (-200) y: (0)
set rotation style [left-right v]
point in direction (90)
set size to (100) %
switch costume to (cat-a v)
show
clear graphic effects
when flag clicked
set up cat
forever
move (5) steps
end
Think: Even though this chunk only appears once, extracting it is still worth it — the new name makes the main script readable at a glance. Refactoring isn't only about repetition; it's also about naming.
Goal: Take this 15-block script and refactor it into two My Blocks: one for the warm-up moves (turn, wiggle, turn back) and one for the celebration (size up, meow, size down). The main script should read like a recipe.
when flag clicked
turn cw (15) degrees
change x by (5)
change x by (-5)
turn ccw (15) degrees
change size by (10)
play sound (Meow v) until done
change size by (-10)
turn cw (15) degrees
change x by (5)
change x by (-5)
turn ccw (15) degrees
change size by (10)
play sound (Meow v) until done
change size by (-10)
define warm up
turn cw (15) degrees
change x by (5)
change x by (-5)
turn ccw (15) degrees
define celebrate
change size by (10)
play sound (Meow v) until done
change size by (-10)
when flag clicked
repeat (2)
warm up
celebrate
end
Think: Could you go further and bundle warm up + celebrate into a single routine block? Sure. Should you? Maybe — it depends on whether you'll ever want to call them separately.
Mini-Challenge — Hakim's "refactor" that broke 5 min
"It used to work!"
Hakim had a script that made the cat hop, meow, and turn 90° — three times in a row, nine blocks total. He extracted a My Block to clean it up. But now the cat only hops once and won't stop meowing. Here's his result:
define hop meow turn
change y by (30)
play sound (Meow v) until done
change y by (-30)
forever
turn cw (90) degrees
end
when flag clicked
repeat (3)
hop meow turn
end
What went wrong? The original definitely had a single turn ↻ (90) degrees, not a forever loop. What slipped in during the refactor?
Reveal the fix
Hakim accidentally wrapped the turn ↻ (90) degrees in a forever loop inside the define. Now the My Block never returns — the first call enters the forever loop and never comes out. So the cat hops once, meows once, and then spins forever. The repeat (3) on the outside is never reached for its second or third iteration.
The fix is to delete the forever in the define and leave the turn as a single block:
define hop meow turn
change y by (30)
play sound (Meow v) until done
change y by (-30)
turn cw (90) degrees
Now the My Block has four blocks, finishes, returns, and the repeat (3) can do its job. Three hops, three meows, three turns.
Lesson: always test after refactoring. The whole point of refactoring is "no change in behaviour." Click the flag, compare, undo if it broke. Hakim would have caught this on the first flag click if he'd remembered to test.
Recap 3 min
You met the most-used cleanup move in programming: refactoring. Spot a chunk of blocks that repeats (or just one that deserves a name), give it a clear name, extract it into a My Block, replace the original copies with calls to the new block. The behaviour stays exactly the same — that's the rule — but the script becomes shorter, more readable, easier to change, and easier for your future self (or your teammate) to understand. The rule of three is a good trigger: by the third copy-paste, extract. And always test after refactoring: same behaviour or you haven't refactored, you've broken something.
- Refactor
- To restructure code so it's cleaner or clearer without changing what it does. The "without changing" part is the whole point.
- Extract (a block)
- To take a chunk of blocks out of a long script and put it inside a new My Block's define stack — then call the My Block where the chunk used to be.
- Rule of three
- A programmer's guideline: by the third time you copy-paste the same code, extract it into a function (here, a My Block).
- Self-documenting code
- Code so well-named that you barely need comments to read it. hop and meow is self-documenting; three nameless blocks doing the same thing are not.
- Behaviour-preserving
- A change is behaviour-preserving when the program does the exact same thing before and after. Every real refactor is behaviour-preserving.
Homework 2 min
The Big Cleanup. Open one of your earlier Scratch projects — one you wrote in Level 2 or earlier in Level 3, before you knew about refactoring. Find one long script. Refactor it.
- Click the flag and write down what the project does in one sentence.
- Find at least one chunk that repeats (or one that deserves a name). Extract it into a My Block with a clear name.
- Click the flag again. Confirm it does exactly the same thing as before. If not, undo and try again.
- Save as
HW-L3-18-Refactor.sb3alongside the original (don't overwrite!) so you can show me the before and after.
Bring back next class:
- Both files — the original and the refactored version.
- Your answer to: "How many blocks did the main script have before? How many after? What name did you choose for the My Block, and why?"
Heads up for next class: SCR-L03-19 uses everything in this cluster — inputs, run without screen refresh, and refactoring — to build a single star (points) (size) block that can draw any star you want. Pure tool-making.