print message if user does nothing for x seconds?

B

Ben Thomas

Hi all,

Only just started using ruby so this may be really simple to do, but
here goes:

I'm trying to write a program that asks a user to enter their sex using
"gets" but if the user doesn't type anything for about 5 seconds I want
to print a message, like "Please enter something..." then go back to the
gets prompt. I've tried using the "sleep x" method but it doesn't seem
to work because once gets has been initiated it gets stuck there until
something is entered.

Oh I don't have to use gets, but this is the only method of input I'm
aware of at the moment

Hope this makes sense,
Ben
 
H

Hal Fulton

Ben said:
Hi all,

Only just started using ruby so this may be really simple to do, but
here goes:

I'm trying to write a program that asks a user to enter their sex using
"gets" but if the user doesn't type anything for about 5 seconds I want
to print a message, like "Please enter something..." then go back to the
gets prompt. I've tried using the "sleep x" method but it doesn't seem
to work because once gets has been initiated it gets stuck there until
something is entered.

Oh I don't have to use gets, but this is the only method of input I'm
aware of at the moment


This is tricky on Windows... what platform are you on?

Hal
 
B

Ben Thomas

Hal said:
This is tricky on Windows... what platform are you on?

Hal

Windows... D'oh!

Is there any better ways to get input from the user that'd make is easier?
 
A

ara.t.howard

Hi all,

Only just started using ruby so this may be really simple to do, but here
goes:

I'm trying to write a program that asks a user to enter their sex using
"gets" but if the user doesn't type anything for about 5 seconds I want to
print a message, like "Please enter something..." then go back to the gets
prompt. I've tried using the "sleep x" method but it doesn't seem to work
because once gets has been initiated it gets stuck there until something is
entered.

Oh I don't have to use gets, but this is the only method of input I'm aware
of at the moment

Hope this makes sense,
Ben


if you're on windows give up now. otherwise try this:

harp:~ > cat a.rb
require 'timeout'

def prompt question, opts = {}
timeout = Integer(opts['timeout'] || opts[:timeout] || 42)
max = Integer(opts['max'] || opts[:max] || 42)
default = opts['default'] || opts[:default]
prod = (opts['prod'] || opts[:prod] || 'hey! wake up!').to_s

answer = default
prompt = "\r#{ question }: "
prod = "\r#{ prod }"

if prompt.size > prod.size
prod += (' ' * (prompt.size - prod.size))
end
if prod.size > prompt.size
prompt += (' ' * (prod.size - prompt.size))
end

max.times{
begin
print prompt
STDOUT.flush
Timeout::timeout(timeout){ answer = gets }
break
rescue Timeout::Error
print prod
STDOUT.flush
sleep 2
end
}

answer
end

answer = prompt 'the question', 'timeout' => 5, 'max' => 2

p 'answer' => answer




-a
 
D

David Vallner

--------------enig3B870C71D6967C8A8EA3F190
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Ben said:
Hi all,
=20
Only just started using ruby so this may be really simple to do, but
here goes:
=20
I'm trying to write a program that asks a user to enter their sex using=
"gets" but if the user doesn't type anything for about 5 seconds I want=
to print a message, like "Please enter something..." then go back to th= e
gets prompt. I've tried using the "sleep x" method but it doesn't seem
to work because once gets has been initiated it gets stuck there until
something is entered.
=20
Oh I don't have to use gets, but this is the only method of input I'm
aware of at the moment
=20
Hope this makes sense,
Ben
=20
=20

Read the data in a thread, or use nonblocking io (currently crude at
best, with only eventmachine to help as a project that shown up on my
radar - and that seems to be oriented towards networking)

Also, what you describe there is a very rude thing to do to your user,
basically you're accusing them of having no attention span and the
program is attention-seeking to compensate.

David Vallner


--------------enig3B870C71D6967C8A8EA3F190
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFVi5/y6MhrS8astoRAjKmAJ9nLzbsQR2Sr/im02Dp+G2d7YB48ACdHyOc
9+cdlFLtQ/6UxwtEGg+Bh/c=
=/RCs
-----END PGP SIGNATURE-----

--------------enig3B870C71D6967C8A8EA3F190--
 
B

Ben Thomas

David said:
Read the data in a thread, or use nonblocking io (currently crude at
best, with only eventmachine to help as a project that shown up on my
radar - and that seems to be oriented towards networking)

Also, what you describe there is a very rude thing to do to your user,
basically you're accusing them of having no attention span and the
program is attention-seeking to compensate.

David Vallner

Yeah, I'd never even think of doing it normally, it was just put in a
small program specification for uni. It's not an assignment or anything
so I'll probably just leave that part out if it's hard to implement.

The part of the specification was:

3. Keep the program running until the user shouts “BYE”. If, while
the program is running, nothing is happening Grandma should shout
“WHAT? CAT GOT YOUR TONGUE? SPEAK UP, I SAY!"


I'll just leave the "cat got your tongue" part out for now. Managed to
keep the program running until the user shouts "BYE" easy enough, just
the second part causing problems.

Thanks for the help.
 
G

Gabriele Marrone

if you're on windows give up now. otherwise try this:

harp:~ > cat a.rb
require 'timeout'

def prompt question, opts = {}
timeout = Integer(opts['timeout'] || opts[:timeout] || 42)
max = Integer(opts['max'] || opts[:max] || 42)
default = opts['default'] || opts[:default]
prod = (opts['prod'] || opts[:prod] || 'hey! wake up!').to_s

answer = default
prompt = "\r#{ question }: "
prod = "\r#{ prod }"

if prompt.size > prod.size
prod += (' ' * (prompt.size - prod.size))
end
if prod.size > prompt.size
prompt += (' ' * (prod.size - prompt.size))
end

max.times{
begin
print prompt
STDOUT.flush
Timeout::timeout(timeout){ answer = gets }
break
rescue Timeout::Error
print prod
STDOUT.flush
sleep 2
end
}

answer
end

answer = prompt 'the question', 'timeout' => 5, 'max' => 2

p 'answer' => answer

Nice! May I suggest adding an optional validation block?
I hope you don't mind if I slightly modify your code:


def prompt question, opts = {}, &validation
timeout = Integer(opts['timeout'] || opts[:timeout] || 42)
max = Integer(opts['max'] || opts[:max] || 42)
default = opts['default'] || opts[:default]
prod = (opts['prod'] || opts[:prod] || 'hey! wake up!').to_s
invalid = (opts['invalid'] || opts[:invalid] || 'try again').to_s

answer = default
prompt = "\r#{ question }: "
prod = "\r#{ prod }"

if prompt.size > prod.size
prod += (' ' * (prompt.size - prod.size))
end
if prod.size > prompt.size
prompt += (' ' * (prod.size - prompt.size))
end

max.times{
begin
print prompt
STDOUT.flush
Timeout::timeout(timeout){ answer = gets }
if validation && !validation.call(answer)
answer = default
puts invalid
else
break
end
rescue Timeout::Error
print prod
STDOUT.flush
sleep 2
end
}

answer
end


answer = prompt('the question', 'timeout' => 5, 'max' => 2) { |s| s
== "valid input\n" }
 
B

Ben Thomas

Hi all,

Only just started using ruby so this may be really simple to do, but
here goes:

I'm trying to write a program that asks a user to enter their sex
using "gets" but if the user doesn't type anything for about 5 seconds
I want to print a message, like "Please enter something..." then go
back to the gets prompt. I've tried using the "sleep x" method but it
doesn't seem to work because once gets has been initiated it gets
stuck there until something is entered.

Oh I don't have to use gets, but this is the only method of input I'm
aware of at the moment

Hope this makes sense,
Ben


if you're on windows give up now. otherwise try this:

harp:~ > cat a.rb
require 'timeout'

def prompt question, opts = {}
timeout = Integer(opts['timeout'] || opts[:timeout] || 42)
max = Integer(opts['max'] || opts[:max] || 42)
default = opts['default'] || opts[:default]
prod = (opts['prod'] || opts[:prod] || 'hey! wake up!').to_s

answer = default
prompt = "\r#{ question }: "
prod = "\r#{ prod }"

if prompt.size > prod.size
prod += (' ' * (prompt.size - prod.size))
end
if prod.size > prompt.size
prompt += (' ' * (prod.size - prompt.size))
end

max.times{
begin
print prompt
STDOUT.flush
Timeout::timeout(timeout){ answer = gets }
break
rescue Timeout::Error
print prod
STDOUT.flush
sleep 2
end
}

answer
end

answer = prompt 'the question', 'timeout' => 5, 'max' => 2

p 'answer' => answer




-a

Thanks for the reply. Unfortunately I am on windows.
 
H

Hal Fulton

Ben said:
Thanks for the reply. Unfortunately I am on windows.

Actually I think this should partially work on Windows.

As I recall, I found that as long as the user typed
*nothing*, timeout was possible. But if the user
typed a character or more and just didn't finish, it
wouldn't time out.


Hal
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top