# Select only taking alternating values?

**URL:** <https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259>\
**Category:** Ruby\
**Created:** [November 20, 2009, 4:12pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259 "2009-11-20T16:12:45Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 20, 2009, 4:12pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/1 "2009-11-20T16:12:45Z")

</div>

The problem in question seems to be that only every OTHER line of  
terminal input is handled by elsif input == STDIN. Here is the complete  
code, with some masked stuff

Code:

require ‘socket’  
require ‘protocol.rb’

#Settings for the server we’re connecting too

class AmityClient

include AmityPackets

def initialize

```
#Bool to check if we've received a Ctrl-C, so we can shut down and

```

clean up nicely.  
@interrupted = false

```
@hostname = "MASKED"
@port = 6002
@username = "amity"
@mppass = "MASKED"

begin
  puts "Trying to connect to #{@hostname} on #{@port}"
  @sock = TCPSocket.new(@hostname, @port)
  sendLogin(@sock, @username, @mppass)
  sendChat(@sock, "-- Amity b0.1 connected --")
  run()
rescue IOError
  puts "-- Socket closed --"
rescue
  puts "Error: #{$!}"
end

```

end

def run  
while 1 #Enter Infinite Loop

```
#Trap a Ctrl-C, and turn on interrupted
trap("INT") {@interrupted = true}

#select input
results = select([@sock, STDIN], nil, nil)
  if results != nil then
    for input in results[0]
      if input == @sock then #Socket Input found
        #Socket stuff here
      elsif input == STDIN #Standard Input found
        if gets.chomp! == "!quit" then
          cleanupAndExit
        else
          puts gets.chomp!
        end
      end #if
    end #for
  end #if

if @interrupted
  puts "\nInterrupted! Cleaning up..."
  cleanupAndExit
end

end #while

```

end #def

def cleanupAndExit  
@sock.close  
sendChat(@sock, “User quit Amity Client”)  
exit  
end

end

interrupted = false

trap(“INT”) {interrupted = true}

amity = AmityClient.new

if interrupted  
puts “Interrupted”  
exit  
end

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 20, 2009, 5:55pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/2 "2009-11-20T17:55:48Z")

</div>

On 11/20/2009 04:12 PM, Dylan Lukes wrote:

> The problem in question seems to be that only every OTHER line of  
> terminal input is handled by elsif input == STDIN. Here is the complete  
> code, with some masked stuff

Think about it for a moment: do you believe that such an obvious error  
in select could have slipped by all tests? No? OK, I don’t either.  
🙂

The bug is with 99% likeliness in your code. You have a bug in your  
input reading code. Look at how you use gets.

Cheers

robert

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 20, 2009, 6:12pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/3 "2009-11-20T18:12:42Z")

</div>

```
        if gets.chomp! == "!quit" then
          cleanupAndExit
        else
          puts gets.chomp!
        end

```

Note how gets is called twice.

Incidentally, a plain gets is _not_ the same as STDIN.gets, but is more  
like ARGF.gets. It makes a difference when someone puts some arguments  
on the command line. Use STDIN.gets to be safe.

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 20, 2009, 6:14pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/4 "2009-11-20T18:14:48Z")

</div>

Brian C. wrote:

> ```
> if gets.chomp! == "!quit" then
> cleanupAndExit
> else
> puts gets.chomp!
> end
> 
> ```
> 
> Note how gets is called twice.

Also, I have a question…

```
results = select([@sock, STDIN], nil, nil)

    for input in results[0]
      [...]
    end #for
  end #if

```

Instead of doing a for loop - just do “results[0].each”, which is more  
idiomatic.  
The question is, what does “select” do ? rdocs aren’t helpful, and I  
don’t understand that bit of code.

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 21, 2009, 3:27pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/5 "2009-11-21T15:27:23Z")

</div>

Brian C.:

> Incidentally, a plain gets is _not_ the same as STDIN.gets, but is  
> more like ARGF.gets. It makes a difference when someone puts some  
> arguments on the command line. Use STDIN.gets to be safe.

Or, better yet, use $stdin.gets â€“ IMHO in general itâ€™s better to use the  
global variables ($stdin, $stdout, $stderr) rather than the constants  
(STDIN, STDOUT, STDERR), because you can repoint the variables as you  
see fit without generating a Ruby warning.

For example, when specing my â€˜executableâ€™ classes with RSpec,  
I often want to specify that something should show up on the  
standard error, and I usually do something like this:

module Signore describe Executable do

before do  
@orig\_stderr = $stderr  
$stderr = StringIO.new  
end

after do  
$stderr = @orig\_stderr  
end

def stderr  
$stderr.rewind  
$stderr.read  
end

it ‘should print usage if no command was given’ do  
lambda { Executable.new([]) }.should raise\_error SystemExit  
stderr.should match /usage: signore prego|pronto [label, â€¦]/  
end

# â€¦

end end

â€” Shot

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 21, 2009, 5:50pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/6 "2009-11-21T17:50:46Z")

</div>

On 20.11.2009 18:14, Aldric G. wrote:

> ```
> results = select([@sock, STDIN], nil, nil)
> 
> for input in results[0]
> [...]
> end #for
> end #if
> 
> ```
> 
> Instead of doing a for loop - just do “results[0].each”, which is more  
> idiomatic.

Absolutely. Usually one would do

ios = […]

in, = select(ios)

in.each do |io|  
data = io.read\_nonblock 1024  
…  
end

> The question is, what does “select” do ? rdocs aren’t helpful, and I  
> don’t understand that bit of code.

See Brian’s explanation.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![revenantphoenix](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/8edcca/32.png) [@revenantphoenix](https://www.ruby-forum.com/u/revenantphoenix)\
**Post date:** [November 20, 2009, 8:14pm UTC](https://www.ruby-forum.com/t/select-only-taking-alternating-values/179259/7 "2009-11-20T20:14:20Z")

</div>

Aldric G. wrote:

> The question is, what does “select” do ? rdocs aren’t helpful, and I  
> don’t understand that bit of code.

You’re right, “ri Kernel#select” and “ri IO::select” are both extremely  
poor.

But it’s essentially the same as the C “select” call, which you can read  
about using “man 2 select” if you have the right manpages installed  
(under Ubuntu: sudo apt-get manpages-dev)

It checks a number of IO descriptors for readiness for reading, writing  
or exceptional conditions, and returns when at least one of them is  
ready or a timeout has expired.

```
select([@sock, STDIN], nil, nil)

```

has no timeout parameter so will wait indefinitely. Only read\_fds are  
specified, so it will return an array containing either @sock or STDIN  
or both, depending on which of them has data to read.
