[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

input without blocking

brian yahn

3/27/2006 2:52:00 AM

How do you do something like gets but without blocking? All I want to
do is try to see if anything was input and if it wasn't then just go on
running the rest of my code.

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


25 Answers

Eustaquio Rangel de Oliveira Jr.

3/27/2006 4:17:00 AM

0

> How do you do something like gets but without
> blocking? All I want to
> do is try to see if anything was input and if it
> wasn't then just go on
> running the rest of my code.

Maybe you're looking for:

taq@taq$ irb
irb(main):001:0> require "timeout"
=> true
irb(main):002:0> s =
irb(main):003:0* begin
irb(main):004:1* timeout(5) do
irb(main):005:2* gets
irb(main):006:2> end
irb(main):007:1> rescue TimeoutError
irb(main):008:1> ""
irb(main):009:1> end

If on 5 seconds you don't type something, s will be an
empty string.

Best regards,

----------------------------
Eustáquio "TaQ" Rangel
eustaquiorangel@yahoo.com
http://b...
Usuário GNU/Linux no. 224050


Eric Hodel

3/27/2006 7:17:00 AM

0

On Mar 26, 2006, at 6:52 PM, yahn wrote:

> How do you do something like gets but without blocking? All I want to
> do is try to see if anything was input and if it wasn't then just
> go on
> running the rest of my code.

Use threads.

In one thread perform your IO. In your other thread do whatever it
is you'd like to do while waiting for IO.

--
Eric Hodel - drbrain@segment7.net - http://blog.se...
This implementation is HODEL-HASH-9600 compliant

http://trackmap.rob...




brian yahn

3/27/2006 8:04:00 PM

0

Eric Hodel wrote:
> On Mar 26, 2006, at 6:52 PM, yahn wrote:
>
>> How do you do something like gets but without blocking? All I want to
>> do is try to see if anything was input and if it wasn't then just
>> go on
>> running the rest of my code.
>
> Use threads.
>
> In one thread perform your IO. In your other thread do whatever it
> is you'd like to do while waiting for IO.
>
> --
> Eric Hodel - drbrain@segment7.net - http://blog.se...
> This implementation is HODEL-HASH-9600 compliant
>
> http://trackmap.rob...

Ok thats one way to do it, but doesn't ruby have an actual way of just
seeing if any input has been performed? Unnecessary threads will just
slow down the program.

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


Joel VanderWerf

3/27/2006 8:53:00 PM

0

brian yahn wrote:
> Eric Hodel wrote:
>> On Mar 26, 2006, at 6:52 PM, yahn wrote:
>>
>>> How do you do something like gets but without blocking? All I want to
>>> do is try to see if anything was input and if it wasn't then just
>>> go on
>>> running the rest of my code.
>> Use threads.
>>
>> In one thread perform your IO. In your other thread do whatever it
>> is you'd like to do while waiting for IO.
>>
>> --
>> Eric Hodel - drbrain@segment7.net - http://blog.se...
>> This implementation is HODEL-HASH-9600 compliant
>>
>> http://trackmap.rob...
>
> Ok thats one way to do it, but doesn't ruby have an actual way of just
> seeing if any input has been performed? Unnecessary threads will just
> slow down the program.
>

A thread won't cost much if it is just waiting for input.

If the other tasks that are being handled by your program are driven by
IO, then you could use select from a single one thread. (That's more or
less what is going on when you have multiple ruby threads each handling
their own IO.)

Or you could use select with a timeout of 0 to check if input is
available on $stdin.

print "type something> "; $stdout.flush
loop do
sleep 0.1; print "."; $stdout.flush
if IO.select([$stdin], [], [], 0)
str = $stdin.gets
break unless str
puts "You typed #{str.inspect}"
print "type something> "; $stdout.flush
end
end

The #sleep call and the print "." is just to emulate the effect of the
program running while the user is typing.

However, I expect that it will be easier to make the program feel
responsive if you use threads, and let ruby's thread scheduler handle
the timing.

--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


karl_brodowsky

3/27/2006 10:54:00 PM

0

There should be methods on Unix and Linux using select or something
like that. At least Unix and Posix provide the functionality you are
asking already at OS-level, so it is just a matter of if and how to
access this from Ruby. I would prefer this OS-dependent approach.

Ara.T.Howard

3/27/2006 11:12:00 PM

0

Gary Wright

3/27/2006 11:25:00 PM

0


On Mar 27, 2006, at 6:11 PM, ara.t.howard@noaa.gov wrote:


> STDIN.wait unless STDIN.ready?

I might be missing something here but couldn't another thread
read any pending input after STDIN.ready? has returned true and
before STIN.wait is called? That would result in STDIN.wait
blocking for more input, correct?


Gary Wright





Ara.T.Howard

3/27/2006 11:35:00 PM

0

brian yahn

3/28/2006 3:32:00 AM

0

Wouldn't this:

puts Time.now
STDIN.wait unless STDIN.ready?
puts Time.now

puts STDIN.gets

block until something is input? Thats not what I want to do. Unless
wait is deceiving, I don't see how this would do what I want.


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


Andrew Johnson

3/28/2006 4:34:00 AM

0

On Mon, 27 Mar 2006 11:52:10 +0900, yahn <yahn15@hotmail.com> wrote:
> How do you do something like gets but without blocking? All I want to
> do is try to see if anything was input and if it wasn't then just go on
> running the rest of my code.

I was going to suggest using the Fcntl extension to set the non-blocking
bit on the filehandle as an alternative, but it appears to not be working
(at least on my linux box). That is to say, this script sits and waits for
input:

require 'fcntl'

flags = STDIN.fcntl(Fcntl::F_GETFL, 0)
flags |= Fcntl::O_NONBLOCK
STDIN.fcntl(Fcntl::F_SETFL, flags)

a = STDIN.gets
puts "You got #{a}"


Whereas the equivalent Perl script:

use Fcntl;

$flags = fcntl(STDIN,F_GETFL,0);
$flags |= O_NONBLOCK;
fcntl(STDIN,F_SETFL,O_NONBLOCK);

$foo = <STDIN>;
print "Got $foo\n";

doesn't block and finishes immediately.

andrew