qazwart has asked for the wisdom of the Perl Monks concerning the following question:

UPDATE: Never mind. I figured it out. It was doing exactly what it was support to do.

The real problem was my code in the previous section.


In my application, I ask for the user's input, but if the user presses a "Ctrl-H", I want to display a help screen, and if the user presses a "Ctrl-P", I want to go back to the previous question.

I've found the "Term::ReadKey" module and did a small little test:

#! /usr/bin/env perl use strict; use warnings; use Term::ReadKey; ReadMode "raw"; my $key = ReadKey(0); ReadMode "restore"; print "Backspace detected!\n" if ($key eq "^H"); my $foo = <STDIN>; print "ASCII Code Value = " . ord($key) . "\n"; print "Complete Answer = " . $key . $foo . "\n"; print "You typed a \"$key\"\n";
Works like a charm! Now, I apply this same technique to my program:
print "\n\nANSWER"; if (defined($default)) { print " [Default = $default]"; } print ": "; ReadMode "raw"; my $key = ReadKey(0); ReadMode "restore"; if ($key eq "^H") { #Help Mode! $showHelpFlag = 1; redo; } chomp($answer = $key . <STDIN>);
No good! When I print the value of "$key", it shows the correct ASCII value, but it doesn't seem to read control characters, so it simply ignores "Ctrl-H" presses.

So, why does the test program work, but the same code in my more complex program doesn't? BTW, the code is in a part where I redefined the package name. I'm making a feeble attempting to do object oriented programming. Would this do anything?

Replies are listed 'Best First'.
Re: Reading Single Character Input with Term::ReadKey
by BrowserUk (Patriarch) on Apr 17, 2007 at 18:20 UTC

    Try changing "^H" for "\cH" or "\x08". "^H" is just a 2 character string consisting of the characters '^' & 'H'. The other two are escape sequences that perl interprets at compile time and substitutes the approriate single control chracter, chr(8).

    Indeed, it might be clearer to others and yourself later if you used

    if ($key eq chr(8) ) { #Help Mode!

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Even clearer would be to hide that in a constant rather than having a bare magic number . . .

      use constant HELP_KEY => chr( 8 ); ## Control H if( HELP_KEY() eq $key ) { ## . . . }

      Alternately:

      use Readonly; Readonly my $HELP_KEY => chr( 8 ); ## Control H if( $HELP_KEY eq $key ) { ## . . . }

        I agree, but it is different advice.

        I was making suggestions on how best to define the constant. You are suggesting that he should use a symbolic constant in place of the actual constant.

        Ie. You could have made your point by suggesting

        use constant HELP_KEY => "\cH"; ## Control H

        And my point would still hold.

        As for Readonly; I "Just Say No", but that's apparently controversial :)


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Reading Single Character Input with Term::ReadKey
by shmem (Chancellor) on Apr 17, 2007 at 18:16 UTC
    Maybe you'd do better saying
    if ($key eq "\cH") { ... }
    and in your sample snippet you're not printing that char.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}