I’ve just read an excellent article about refactoring rcat in Rubies in the
Rough. If you are not
subscribed you should be… I couldn’t
resist to take a swing at it and refactor Display class since
thats where most of the action is happening. In one line rcat is supposed to behave as Unix cat command for some basic cases.
This is original implementation, great stuff from the
Practicing Ruby.
classDisplaydefinitialize(params)@line_numbering_style=params[:line_numbering_style]@squeeze_extra_newlines=params[:squeeze_extra_newlines]enddefrender(data)@line_number=1lines=data.linesloop{render_line(lines)}endprivateattr_reader:line_numbering_style,:squeeze_extra_newlines,:line_numberdefrender_line(lines)current_line=lines.nextcurrent_line_is_blank=current_line.chomp.empty?caseline_numbering_stylewhen:all_linesprint_labeled_line(current_line)increment_line_numberwhen:significant_linesifcurrent_line_is_blankprint_unlabeled_line(current_line)# skip incrementing line number, want to only count significant lineselseprint_labeled_line(current_line)increment_line_numberendelseprint_unlabeled_line(current_line)increment_line_numberendifsqueeze_extra_newlines&¤t_line_is_blanklines.nextwhilelines.peek.chomp.empty?endenddefprint_labeled_line(line)print"#{line_number.to_s.rjust(6)}\t#{line}"enddefprint_unlabeled_line(line)printlineenddefincrement_line_number@line_number+=1endend
I’ve liked @JEG2 idea about not using loop and about trimming down
render_line method a bit. I did not like the use of additional object
that will carry state. This is what I’ve ended up with:
I like the last example the best because domain is really starting to
show. I get to talk about being blank or significant etc… In theory
.each_cons(2) seems to be better suited than .reduce for the job of “sliding” trough lines,
but I am unable to make it work that way. (@ryanlecompte suggested it
since I completely forgot about that method.)
Also it looks to me as if I need “Line” class that would have blank?,
significant? and numbered? methods. Probably also “Configuration” class
for line style. But that is something I would do if things begin to get
complex, right now there is no need. I am pretty pleased on how the code
is communicating what it is suppose to do.