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

This is a REALLY stupid question, but how come this does not just accept the keyboard input (with <enter> key) then immediately print it out, then quit. The script doesn't do the print and i can't stop it without using ^c
This is not on a webpage, it's using the perl interpreter directly; i.e. "perl input.pl" at the command prompt

print "type something: "; my($input) = <STDIN>; print "you typed ", $input;

I tried re-inventing the wheel again, but everytime I push it, it still falls flat on it's side...

Replies are listed 'Best First'.
Input problem with Enter key...
by davido (Cardinal) on Nov 07, 2016 at 01:02 UTC

    In list context the file input operator (<...>) reads an entire file, stopping when it reaches EOF (end of file). Typical file handling does not equate "newline" (\n) to indicate EOF. By wrapping $input in parenthesis, you are implying to Perl that the item on the lefthand side of the = assignment operator is a list. That puts <STDIN> into list context, so the entire file is slurped in.

    But what is the entire file, when dealing with a terminal? Under linux environments one can inject an EOF in terminal input by hitting ctrl-D. This may vary by operating system.

    If your line was this instead:

    my $input = <STDIN>;

    ...then the righthand side of the assignment is cast in scalar context. In scalar context, the <> operator reads a single record. Unless it's been changed elsewhere in the program, the record separator is newline. So when you type something and hit enter, you effectively send one record through STDIN to $input.


    Dave

      I changed what you indicated and dropped the parenthisis. But when i "run" the script, it still moves to the next line and waits for more input until i hit ^c to exith the interpeter, to which it prints the "input" when exiting. Do i need to change a $| or something, it still is doing the same thing.

      print "Something: "; my $Input = <STDIN>; print "You Typed ", $Input;

      I tried re-inventing the wheel again, but everytime I push it, it still falls flat on it's side...

        Does your program contain any lines that manipulate the special variable, $/?

        use strict; use warnings; $/ = undef; print "Say something: " my $Input = <STDIN>; print "You typed $Input\n';

        It sounds like either your script, or a module your script uses has altered $/. At least that's the first thing that jumps to mind for me. There are probably other ways to arrive at that type of behavior, but that's one of the easiest ones to arrive at.

        By the way, a better way to gather user input may be found buried in the core Perl module, ExtUtils::MakeMaker:

        use ExtUtils::MakeMaker q(prompt); my $input = prompt('Say something: '); print "You typed $input\n";

        prompt() allows you to set a default value, and uses that default if the user hits enter without typing anything, or if it detects a non-interactive environment.


        Dave

        I am unable to (and, frankly, didn't expect to be able to) reproduce your problem in isolation. I tried this:

        $ perl -e 'print "X: "; my $x = <STDIN>; print "X=", $x'

        Regardless, of whether I terminate the input with <Enter>, Ctrl-J (newline) or Ctrl-M (carriage return), it works fine:

        $ perl -e 'print "X: "; my $x = <STDIN>; print "X=", $x' X: 123 X=123 $

        Adding '$|=0;' or '$|=1;', as the first statement, makes no difference: I get the same result as above (regardless of how I terminate the input).

        Try what I did and see how you go. If it works OK, then there's probably something else in your code causing the problem; if it's still not working, look for issues with whatever shell you're running, non-standard keymapping, hardware problems (perhaps try starting a new shell or even rebooting).

        — Ken