Pharo refactor loop (live image, via the genie MCP tools)
Refactoring = change structure without changing behavior. The proof that
behavior is unchanged is a green test suite before AND after. All reads and
writes go through the genie MCP tools; there are no files. Change code only
via define_method / define_class / rename_class / remove_method /
eval, and read every change back to confirm it.
Loop
Green baseline. Run
run_teston the relevant class/package. If the code you're about to touch has NO test coverage, STOP and write characterization tests first (use thepharo-tddskill) — you cannot refactor safely without a safety net.Map impact. Before any rename/move/extract, find every caller and implementor:
search_references/search_references_to_class— who uses itsearch_implementors— who else defines this selectorsearch_methods_like— similar code that may need the same change Make a list. Every item gets updated in this same session.
One small change. Make a single structured edit. Read changed methods back with
get_method_source.Re-test. Run
run_test(class, then package). Green → keep going. Red → the trace shows what broke; fix or revert this one step before moving on. Never batch unverified edits.Repeat steps 3–4 in small increments until the cleanup is complete.
Done. Persist with
save_imagegated on the test package. Summarize the before/after shape.
Common moves
- Rename class: use
rename_class— it updates every code reference and symbol literal via the refactoring engine. It does NOT touch string literals, so fix stringly-typed names by hand; and in a test that renames a class, refer to the old name as'Foo' asSymbol, never#Foo, or the test rewrites its own assertion and self-mangles. - Remove method:
remove_method. Remove class:remove_class. - Rename method: install the new selector via
define_method, repoint every sender (fromsearch_references), thenremove_methodthe old one. - Extract method: add the new helper, call it from the original, re-test.
Rules
- Behavior-preserving only. If a test changes meaning, that's a feature change
— do it under
pharo-tdd, not here. - Small steps, tests between each. A long unverified refactor is a bug factory.
- Modern class API only (
ShiftClassInstaller/define_class).