1
\$\begingroup\$

I've got the following code, which works, but seems repetitive. Under DRY principle, how can I clean this up?

puts "Blurt out a word"
word = gets.chomp
word_list = []
word_list.push word
until word == ""
 word = gets.chomp
 word_list.push word
end
puts word_list.sort
Nat
1,0261 gold badge7 silver badges15 bronze badges
asked Aug 14, 2012 at 18:13
\$\endgroup\$
0

3 Answers 3

6
\$\begingroup\$
puts "Blurt out a word"
word_list = []
while word_list.last != ""
 word_list << gets.chomp
end
puts word_list.sort

If you prefer the until:

puts "Blurt out a word"
word_list = []
until word_list.last == ""
 word_list << gets.chomp
end
puts word_list.sort

You can also do it shorter:

puts "Blurt out a word"
word_list = []
word_list << gets.chomp until word_list.last == "" 
puts word_list.sort

Remark: The last (empty) line is also returned. To skip the empty line you may use:

puts word_list[0..-2].sort
answered Aug 14, 2012 at 19:02
\$\endgroup\$
0
2
\$\begingroup\$

Perhaps

puts 'Blurt..'
puts STDIN.take_while{|line| line !~ /^$/}.map(&:chomp).sort

Edit: Why is this better? Because unlike other approaches it never modifies a variable that is assigned once. Thus it preserves the referential integrity. That is this is a functional programming approach in comparison with others which (as of now) follow an imperative model. The succinctness that results from it is just a bonus.

answered Aug 14, 2012 at 23:16
\$\endgroup\$
4
  • \$\begingroup\$ you code solo, don't you? \$\endgroup\$ Commented Aug 15, 2012 at 19:24
  • \$\begingroup\$ too hard to read? \$\endgroup\$ Commented Aug 16, 2012 at 2:51
  • \$\begingroup\$ i can read it just fine, understanding what it is doing is taking a lot longer than it should. \$\endgroup\$ Commented Aug 16, 2012 at 13:55
  • \$\begingroup\$ +1. @Ryan: This is simple functional programming style, IMO we should expect a competent team to have no problems with it. @rahul: If you have the abstraction String#present? you can even write a slightly more declarative STDIN.take_while(&:present?).map(&:chomp).sort. \$\endgroup\$ Commented Aug 25, 2012 at 19:26
1
\$\begingroup\$

Keeping as much of your style as possible, the simple way to avoid repetition is to pull the repetitive phrases inside your loop.

Now I'm assuming that what prevented you from doing this was the fact that Ruby's 'until' loop evaluates the exit condition at the top of the loop, which will therefore throw an error unless you've initialised 'word'.

This inconvenience can be avoided by moving from an 'until' loop to an infinite loop with an internal test / decision / exit condition, like so:

puts "Blurt out a word"
word_list = []
loop do
word= gets.chomp
 if word == "" 
 break
 else 
 word_list.push word
 end 
end
puts word_list.sort

Now 'word' is defined before the exit condition is evaluated. And as a useful aside, a blank entry is not inserted into 'word_list'.

There are of course many other ways of doing this -- Ruby allows for cleverness over clarity. The above simply refactors your code and removes the repetition.

answered Aug 15, 2012 at 19:20
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.