Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

select only taking alternating values?

0 views
Skip to first unread message

Dylan Lukes

unread,
Nov 20, 2009, 10:12:48 AM11/20/09
to
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/.

Robert Klemme

unread,
Nov 20, 2009, 11:51:50 AM11/20/09
to
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

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

Brian Candler

unread,
Nov 20, 2009, 12:12:57 PM11/20/09
to
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.

Aldric Giacomoni

unread,
Nov 20, 2009, 12:14:54 PM11/20/09
to
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.

Brian Candler

unread,
Nov 20, 2009, 2:21:25 PM11/20/09
to
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.

Robert Klemme

unread,
Nov 21, 2009, 11:48:59 AM11/21/09
to
On 20.11.2009 18:14, Aldric Giacomoni wrote:
> 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

0 new messages