Select only taking alternating values?

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

···

--
Posted via http://www.ruby-forum.com/.

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. :slight_smile:

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

···

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

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

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.

···

--
Posted via http://www.ruby-forum.com/.

Brian Candler 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.

···

--
Posted via http://www.ruby-forum.com/\.

Brian Candler:

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

···

--
a :message to you, Ruby

Aldric Giacomoni 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.

···

--
Posted via http://www.ruby-forum.com/\.

Brian Candler 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.

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

···

On 20.11.2009 18:14, Aldric Giacomoni wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/