Ruby Science
Rename Method
Renaming a method allows developers to improve the language of the domain as their understanding naturally evolves during development.
The process is straightforward if there aren’t too many references:
- Choose a new name for the method. This is the hard part!
- Change the method definition to the new name.
- Find and replace all references to the old name.
If there are a large number of references to the method you want to rename, you can rename the callers one at a time while keeping everything in working order. The process is mostly the same:
- Choose a new name for the method.
- Give the method its new name.
- Add an alias to keep the old name working.
- Find and replace all references to the old name.
- Remove the alias.
Uses
- Eliminate uncommunicative names.
- Change method names to conform to common interfaces.
Example
In our example application, we generate summaries from answers to surveys. We allow more than one type of summary, so strategies are employed to handle the variations. There are a number of methods and dependencies that make this work.
SummariesController#show depends on
Survey#summarize:
# app/controllers/summaries_controller.rb
@summaries = @survey.summarize(summarizer)Survey#summarize depends on
Question#summarize:
# app/models/survey.rb
def summarize(summarizer)
questions.map do |question|
question.summarize(summarizer)
end
endQuestion#summarize depends on summarize
from its summarizer argument (a strategy):
# app/models/question.rb
def summarize(summarizer)
value = summarizer.summarize(self)
Summary.new(title, value)
endThere are several summarizer classes, each of which respond to
summarize.
This is confusing, largely because the word summarize is
used to mean several different things:
Survey#summarizeaccepts a summarizer and returns an array ofSummaryinstances.Question#summarizeaccepts a summarizer and returns a singleSummaryinstance.summarizeon summarizer strategies accepts aQuestionand returns aString.
Let’s rename these methods so that each name is used uniquely and consistently in terms of what it accepts, what it returns and what it does.
First, we’ll rename Survey#summarize to reflect the fact
that it returns a collection.
# app/models/survey.rb
def summaries_using(summarizer)Then we’ll update the only reference to the old method:
# app/controllers/summaries_controller.rb
@summaries = @survey.summaries_using(summarizer)Next, we’ll rename Question#summarize to be consistent
with the naming introduced in Survey:
# app/models/question.rb
def summary_using(summarizer)Finally, we’ll update the only reference in
Survey#summaries_using:
# app/models/survey.rb
question.summary_using(summarizer)We now have consistent and clearer naming:
summarizemeans taking a question and returning a string value representing its answers.summary_usingmeans taking a summarizer and using it to build aSummary.summaries_usingmeans taking a set of questions and building aSummaryfor each one.
Next Steps
- Check for explanatory comments that are no longer necessary now that the code is clearer.
- If the new name for a method is long, see if you can extract methods from it to make it smaller.
Ruby Science
The canonical reference for writing fantastic Rails applications from authors who have created hundreds.