in reply to Re: CGI, STDIN and chomp problem: bug?
in thread CGI, STDIN and chomp problem: bug?

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?

Replies are listed 'Best First'.
Re^3: CGI, STDIN and chomp problem: bug? (input)
by tye (Sage) on Jul 14, 2007 at 16:25 UTC

    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        

      Now, if you want to actually explain why you think it makes sense to combine CGI.pm with interactive input...

      I apologise once again, I was trying to keep it simple, reducing the problem to the simplest case...

      As it is, I see more explanation is in order. I have a perl script using sqlite that works very well. Very much simplified, it looks like this:

      use strict; use warnings; use DBI; my @fields = ( qw/ Genus Species Cultivar Common_Name / ); my $field = get_field( @fields ); my $value = get_value( $field ); # Omitted: code to connect to DB my $select_query = qq/ select * from plant where $field = '$value' /; # Omitted: code to execute, fetch and deallocate SQL query sub get_field { # Highly simplified for testing purposes return $_[3]; } sub get_value { print $_[0], ': '; chomp ( my $choice = <STDIN> ); # <- Problem here! return $choice; }
      ...by telling us more about what you are trying to do...

      I am converting this program to a CGI script. I decided to do the HTML output bit first. Of course, once I have finished, I will not be combining CGI.pm with interactive input once the development phase is finished. However, I was surprised that adding use CGI; to my code added a subtle bug that it took me a very long time to track down.

      ...then we could probably tell you the proper way to prevent this problem

      It's all right, thanks: as I say, I've now tracked down the bug (which thanks to your explanation I accept is in my code, not in CGI.pm :) and found a workaround.

Re^3: CGI, STDIN and chomp problem: bug?
by moritz (Cardinal) on Jul 15, 2007 at 13:56 UTC
    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.

      I'd ask the CGI maintainer to localize $/ anyway before changing it...

      Actually, I took tye's advice above and looked at the CGI.pm source code. Unless I'm very much mistaken, $/ is modified only twice:

      1. On line 489:

      local($/) = "\n";

      where the change is safely localised within a sub, and

      2. On lines 3602-3607:

      my($old); ($old,$/) = ($/,$CRLF); # read a CRLF-delimited line # Some stuff $/ = $old; # restore old line separator

      where it is restored to its former value.

      So, as tye intimated, my problem seems to have nothing to do with the non-localisation of changes to $/ in CGI.pm.