Rename Field
Intent
Section titled “Intent”Field names are the vocabulary of a data structure. When a field is called name but actually holds a customer’s title, or date when it really stores a creation timestamp, the name lies, and every reader pays a small tax to decode it. Rename Field changes the field to a name that matches what it now holds, and updates everything that reads or writes it. The data structure starts telling the truth again.
The smell
Section titled “The smell”The smell is a field name that no longer matches its data. Names drift as software grows: a field added for one purpose gets reused for another, a domain term changes, or the original name was simply vague. You notice it when the name needs a comment to explain it, when newcomers consistently misread it, or when the field’s name and its actual usage have quietly diverged. A stale name is a small but constant source of misunderstanding.
Before → After
Section titled “Before → After”A customer record whose field is called name but holds a formal title. After, it is renamed title, with accessors updated so callers read the clearer name.
// Beforeinterface Customer { name: string; // actually a formal title like "Dr." email: string;}function greet(c: Customer): string { return `Welcome, ${c.name}`;}
// Afterinterface Customer { title: string; email: string;}function greet(c: Customer): string { return `Welcome, ${c.title}`;}# Beforefrom dataclasses import dataclass
@dataclassclass Customer: name: str # actually a formal title like "Dr." email: str
def greet(c): return f"Welcome, {c.name}"
# After@dataclassclass Customer: title: str email: str
def greet(c): return f"Welcome, {c.title}"// Beforetype Customer struct { Name string // actually a formal title like "Dr." Email string}func Greet(c Customer) string { return "Welcome, " + c.Name}
// Aftertype Customer struct { Title string Email string}func Greet(c Customer) string { return "Welcome, " + c.Title}// Beforestruct Customer { name: String, // actually a formal title like "Dr." email: String,}fn greet(c: &Customer) -> String { format!("Welcome, {}", c.name)}
// Afterstruct Customer { title: String, email: String,}fn greet(c: &Customer) -> String { format!("Welcome, {}", c.title)}Mechanics
Section titled “Mechanics”- If the record is small and entirely under your control, your editor’s rename-symbol refactoring can do the whole job in one safe step — use it and run your tests.
- For a widely used or externally shared record, go incrementally. First, if the field is not already encapsulated, hide it behind a getter and setter so callers depend on accessors rather than the raw field.
- Rename the underlying field, keeping the accessors temporarily named for the old name. Run your tests.
- Rename the getter and setter to the new name, updating call sites in small batches. Run your tests after each batch.
- If the field is serialised (JSON, a database column, a wire format), keep the persisted key stable with an explicit mapping — or migrate it deliberately — so you do not break stored data or other services.
- When every reader and writer uses the new name and any serialisation mapping is settled, the rename is complete.
When to use / trade-offs
Section titled “When to use / trade-offs”Rename Field is worth doing the moment a name causes a misread, because the cost of a confusing name compounds with every person who reads it. It is cheapest on small, internal structures where a tool-assisted rename is instant and safe.
The hazard is reach. A field can be referenced far beyond your file: in serialised payloads, database schemas, API contracts, or other repositories you do not control. For those, a blind rename breaks consumers. Decouple the internal name from the external one — map the new field name to the old serialised key — or run a planned migration. When in doubt about who reads the data, encapsulate first and rename behind that boundary.