# Help with Arrays

**URL:** <https://www.ruby-forum.com/t/help-with-arrays/112292>\
**Category:** Ruby\
**Created:** [August 17, 2007, 3:58am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292 "2007-08-17T03:58:26Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 3:58am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/1 "2007-08-17T03:58:26Z")

</div>

I have the following code:

words = []

while gets.chomp != ‘’  
words.push gets.chomp  
end

puts words.sort

Its supposed to capture from the user, a bunch of words, until just  
enter is pressed, and put them in an array. When I run the code, it  
only enters every other word i type into the array. I cannot figure it  
out! I know this is simple for you all, so have pity on me! Im super  
new to ruby and programming in general.

Thanks in advance.

J

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 4:15am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/2 "2007-08-17T04:15:49Z")

</div>

Jonathan — wrote:

> I have the following code:
> 
> words = []
> 
> while gets.chomp != ‘’  
> words.push gets.chomp  
> end

Jonathan,

ruby reads another line each time you call gets or gets.chomp (or  
gets.anything). You need to cache the result of the call to gets(). I  
would write:

while line = gets.chomp && line != “”  
words.push line  
end

Dan

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 4:41am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/3 "2007-08-17T04:41:50Z")

</div>

Jonathan Carbon wrote:

> Hi Dan,
> 
> thanks very much for the response. The program does not seem to get to  
> end when just the enter is pressed…  
> Im doing my best to understand…
> 
> Sorry to be so thick!  
> Not at all, the thickness is mine…

> Thanks!

Giving advice without testing it is a bad habit of mine. I wasn’t paying  
attention to Ruby’s precedence. Apparently,  
while line = gets.chomp && line != “”  
needs some parentheses:  
while (line = gets.chomp) && line != “”

However, there’s another small gotcha. When you write a loop  
while line = gets.chomp; something; end  
users will often end the loop by hitting control-d, which means “end of  
file” (on unix/linux, at least). This causes gets() to return nil, and  
in that case, line.chomp throws an error (nil lacks the method chomp()).

This does what you want and also handles the control-d case:  
while line=gets and line.chomp != “”  
Note that the chomp() is not cached in this case–in the body of the  
loop, you need to call chomp() when you refer to the line, or just call  
“line.chomp!”. You could probably be more efficient, but often the Ruby  
way is either the most easily readable thing, or the most elegant.

Dan

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 4:24am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/4 "2007-08-17T04:24:42Z")

</div>

Dan Z. wrote:

> Jonathan — wrote:
> 
> > I have the following code:
> > 
> > words = []
> > 
> > while gets.chomp != ‘’  
> > words.push gets.chomp  
> > end
> 
> Jonathan,
> 
> ruby reads another line each time you call gets or gets.chomp (or  
> gets.anything). You need to cache the result of the call to gets(). I  
> would write:
> 
> while line = gets.chomp && line != “”  
> words.push line  
> end
> 
> Dan

Hi Dan,

thanks very much for the response. The program does not seem to get to  
end when just the enter is pressed…  
Im doing my best to understand…

Sorry to be so thick!

Thanks!

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 4:51am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/5 "2007-08-17T04:51:45Z")

</div>

Dan,

Many thanks for the extended response. Its much appreciated.

J

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 10:51am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/6 "2007-08-17T10:51:20Z")

</div>

I’d rather do this because the test is much easier:

words = []

while ( line = gets )  
words \<\< line.chomp  
end

However, there is a much shorter solution available:

puts ARGF.readlines.sort

Or even using “sort” directly (on a Unix like system):

$ sort \<\<XXX

> foo  
> bar  
> baz  
> XXX  
> bar  
> baz  
> foo

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 17, 2007, 8:06pm UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/7 "2007-08-17T20:06:25Z")

</div>

On Aug 17, 3:49 am, “Robert K.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> I’d rather do this because the test is much easier:
> 
> words = []
> 
> while ( line = gets )  
> words \<\< line.chomp  
> end

The original poster wants the loop to end when the user presses  
  
without entering any text. How about this?

words = []  
while line = gets and line.chomp! != “”  
words \<\< line  
end

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 18, 2007, 4:58am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/8 "2007-08-18T04:58:14Z")

</div>

From: William J. [[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)]

# From: Robert K. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)

# \> I’d rather do this because the test is much easier:

# \> words = []

# \> while ( line = gets )

# \> words \<\< line.chomp

# \> end

# 

# The original poster wants the loop to end when the user presses

# without entering any text. How about this?

# words = []

# while line = gets and line.chomp! != “”

# words \<\< line

# end

in (my) practice, i usually go the simple way (like robert’s), then  
refine it as needed by just adding the lines.

words = []  
while line=gets # break on eof  
break if line.strip!.empty? # break on empty lines including spaces  
next if line != /\w/ # special chars not allowed

words \<\< line # passed  
end

sometimes, (as a nuby,) putting all conditions in one line may be  
dangerous. it is dificult to test, difficult to comment, and one may  
miss edge cases…  
i know it’s not clever, but i value safety first, and it’s cleaner and  
clearer to me… but ymmv… i haven’t reach the mile yet 🙂

kind regards -botp

---

<div class="post-metadata">

**Author:** ![makki](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/b4bc9f/32.png) [@makki](https://www.ruby-forum.com/u/makki)\
**Post date:** [August 18, 2007, 6:11am UTC](https://www.ruby-forum.com/t/help-with-arrays/112292/9 "2007-08-18T06:11:18Z")

</div>

On Aug 17, 2:04 pm, William J. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> The original poster wants the loop to end when the user presses  
>   
> without entering any text. How about this?
> 
> words = []  
> while line = gets and line.chomp! != “”  
> words \<\< line  
> end

Might as well simply evaluate the assignment expression directly:

words = []  
while (line = gets.chomp) != ‘’  
words \<\< line.chomp  
end  
puts words.sort

While that fulfills the original spec, I agree with Dan’s comment  
regarding -D or EOF. It would be nice to handle that to allow  
piping a file of words to the program. Before I noticed Robert’s post,  
I came up with the following:

puts ARGF.inject([]) {|memo,obj| memo \<\< obj}.sort

although fun, it’s way too verbose. I ended up shortening Robert’s to  
this:

puts ARGF.sort

If you don’t want to create a .rb file, just:

ruby -e ‘puts ARGF.sort’

🙂
