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

UPDATE: It turns out that it was a problem with printing to STDERR in my version of Apache2. Now that I have upgraded Apache2 to the latest Debian packages, the problem is gone. Thanks all for your help.

I'm having trouble with Text::CSV_XS. I'm using it most simply, and I don't understand why things are failing. I am not getting any error messages, the script (which is a CGI-script) just hangs indefinitely, until the web server ultimately times out. I have narrowed the problem down to the following (simplified) function.

Please notice the comments EXAMPLE LINE 1 and EXAMPLE LINE 2. If I comment either one (or both) of those out, everything works fine. If I leave them both as they are now, uncommented, the script hangs and I never get an error message in my error logs. I don't understand what's causing this or how to fix it.

$fh is a filehandle created by CGI.pm and retrieved using my $fh = $cgi->upload('product_list');
sub validate_data { my ($self, $fh) = @_; my $csv = new Text::CSV_XS({sep_char => "\t"}); my $headings = <$fh>; # Pull the column names off the top $csv->parse($headings) or return; my @headings = $csv->fields(); print STDERR Dumper(\@headings); # EXAMPLE LINE 1 while(my $line = <$fh>) { if($csv->parse($line)) { my %hash; my @fields = $csv->fields(); print STDERR Dumper(\@fields); # EXAMPLE LINE 2 } } return 1; }

I am using: I forgot to mention: Dumping this data isn't really the important part. I'm using it to build a data structure, but any time I try to access data in the data structure, the script hangs!

Edit: I have switched to Text::Delimited and when using Dumper to see those results I get errors again. I can access all the values fine, I just can't view them with Dumper. It always hangs and the program won't exit. I have a bad feeling about this.

Replies are listed 'Best First'.
Using Text::CSV_XS to parse a string
by jZed (Prior) on Nov 11, 2004 at 00:42 UTC
    You asked in the CB if Text::CSV_XS could parse from a string, rather than a file. I see you've used the $csv->parse() method to do that here by using <$fh> to read the file. That works ok because you apparently don't have any embedded newlines. If you did have embedded newlines you should use $csv->getline() instead and use it directly on the $fh. You can also use getline() on a string with embedded junk without any file. This correctly shows two records of four fields each:
    #!perl -w use strict; use IO::Scalar; use Text::CSV_XS; my $csv = Text::CSV_XS->new( {binary=>1} ); my $fh = new IO::Scalar; my $str = qq{aa,"b\nb","c,c",7\ndd,ee,ff,8}; $fh->open(\$str); while (my $cols = getline($fh)) { print "<$_>" for @$cols; print "\n"; } sub getline { my $cols = $csv->getline($_[0]); if (!$cols) { die $! if $!; return undef; } return (@$cols) ? $cols : undef; }
      I'm getting my $fh directly from CGI.pm (it's an uploaded file). Last time I tried to pass it directly to a module (in that case was GD::Image), it failed miserably because apparently they use their own kind.
Re: Script Hanging w/Data::Dumper and Text::CSV_XS
by jZed (Prior) on Nov 11, 2004 at 00:32 UTC
    Your script works fine for me. You should add an else clause onto the parsing to see if parsing fails (perhaps the line endings aren't what you expect). Something like
    if($csv->parse($line)){ ... } else { die $csv->error_input }

    BTW, if this is a CGI, did you print the content-header someplace else? Because if you didn't, trying to print the Dumper without a content header will not do what you want.

      His dump prints are going to stderr (and hence into the server's error log) so that shouldn't make a difference one way or the other.

      I have the error checking on my script, I omitted it here because I didn't want the code to be too long. The thing is, the parsing is working fine. The problem is, when I assign the result of the fields() function to some array, and then later use fields() again to a different array, I can't get at the data in the first array. It seems almost like a memory management issue behind perl somewhere because I'm carefully and correctly using scoping here and the array names aren't in conflict at all. I even tried copying the results to a new array but that gives me the hanging as well. If the code is working fine on your machine, I'm betting that it has to be something wrong with the installation or something on my machine :(