I have a Ruby function which generates and saves a report. I'm looking for a Clean Code way of writing this:
def generate
violations = relevant_violations
comments = convert_to_cleaned_up_comments(violations)
text = convert_to_text(comments)
save_to_file(text)
end
But I hate single-use low-semantic-value variables like these. So here's my first re-write:
def generate
save_to_file(
convert_to_text(
convert_to_cleaned_up_comments(
relevant_violations)))
end
And even though the flow is now in the reverse order, I find this quicker to grasp. There's less junk getting in the way.
But maybe a map/reduce or block style of programming would provide the same clarity but show data flow in the direction written, top to bottom.
EDIT: I re-wrote it so that the code can be read mostly top-to-bottom, not bottom-to-top:
corpus.rake — the reporting script
def generate_and_save
save_to_file Violation
.select(&:within_past_30_days?)
.map(&:to_corpus_friendly_comment)
.join "\n"
end
def save_to_file(text)
File.open(LOCAL_PATH, 'w') { |f| f.write text }
end
violation.rb — the Violation class
def to_corpus_friendly_comment
facts
.downcase
.gsub(/\b(\d+f?|\w|pic|inspection)\b/, ' ')
.gsub(/\W/, ' ')
.gsub(/(foods?|please|days|use)/, '')
.gsub(/ +/, ' ')
.strip
end
def within_past_30_days?
date > 30.days.ago
end
...enabled by object-oriented refactoring; moving the functions into the Violations object enabled method chaining. One part I don't like is that .join "\n"
is a lower level of abstraction than the other lines in generate_and_save.
relevant_violations.to_cleaned_up_comments.to_text.save_to_file
:) \$\endgroup\$Worflow [:relevant_violations, :to_cleaned_up_comments, :to_text, :save_to_file]
\$\endgroup\$