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

use CGI; print 'Your input: '; my $var = <STDIN>; chomp $var; print "\$var is '$var'"; # Output: 'var is 'foo

What's happening here? I can work around the problem by changing the chomp line to:

$var =~s/\s+$//; # Output (as expected): $var is 'foo'

I also have no problem when the scalar doesn't come from STDIN, eg:

chomp ( my $var = "foo\n" );

ActiveState perl v5.8.8 (build 819) on WinXP Pro, CGI.pm version 3.20.

Replies are listed 'Best First'.
Re: CGI, STDIN and chomp problem: bug?
by kyle (Abbot) on Jul 14, 2007 at 14:51 UTC

    Well, chomp removes the input record separator (see $/ in perlvar). My guess is that your input record separator is "\n", but your input from <STDIN> has a "\r" in it. So, after $var = <STDIN>, $var ends in either "\r\n" or just "\r". You can take them off like this:

    $var =~ s{ \r \n ? \z }{}xms;

    As an aside, I think using CGI is somewhat misplaced here. If you're on your way to making a CGI script, your input will almost certainly be entirely handled by the CGI module, and you won't need to worry about how your lines are terminated.

      I think using CGI is somewhat misplaced here.

      I'm sorry, my post clearly wasn't specific enough. The whole point is that I only get the problem when I use CGI. If I comment out the use CGI line, chomp removes my newline in the normal fashion.

      However, your answer helped clarify the issue. If I add

      $/= "\r\n";

      at the top of the code, the problem goes away.

      It would seem that CGI.pm resets $/ without localising the change. Bug?

        I'm sorry, Doctor, I wasn't clear enough. I only get the pain when I do *this*, ouch.

        CGI scripts don't read input interactively from users so the "bug" here is your "bug" of trying to use CGI.pm along with stuff that clearly won't work in a CGI script.

        No, I doubt CGI.pm is changing $/. Have you looked at the source code? My guess is that CGI.pm is doing binmode on STDIN (which it makes some sense for it to do).

        Now, if you want to actually explain why you think it makes sense to combine CGI.pm with interactive input, for example, by telling us more about what you are trying to do, then we could probably tell you the proper way to prevent this problem.

        No, setting $/ like you did is not the proper way, actually. Please take a look at what $/ is set to when you don't use CGI.pm. And try not to be confused by the unfortunate wording of perlport. :)

        - tye        

        As was mentioned before, CGI scripts normally don't read from STDIN directly, so it's usually not a pressing issue, but I'd ask the CGI maintainer to localize $/ anyway before changing it.

        If it's really a bug mainly depends on your definition of bug.