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

Hey guys - I recently was working on consuming a query from my database and outputting this information to a CSV file to be emailed to myself. I can't seem to understand why the excel file prints only to 1 row when I do not use eol=>$/ inside the setup parameters for Text::CSV. I imagine this has to do with a carriage return or new line symbol but in my research I have pulled up no information on what $/ means.. Can someone shed some light on this? The following is my working code with the EOL attached, I just don't understand how the EOL is interpretted.
my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1, eol => $/ }); open my $fh, ">:encoding(utf8)", $filename or die "$filename: $!"; $sth = $dbh->prepare("$query") or error($q, "Problem with database cal +l"); if($sth->execute) { while(@dat = $sth->fetchrow) { $csv->print($fh, \@dat) +; }
THANKS!

Replies are listed 'Best First'.
Re: CSV EOL Question
by Tux (Canon) on Jan 22, 2014 at 15:17 UTC

    The default for the eol attribute is undefined, so the parser can parse records ending on any valid line ending: \r, \r\n, and \n. To produce records, the CSV object should know to do line endings, hence you need to set eol.

    It is way to late now to change the default to be sensible and use $/ on print, which would have been a fine choice in the beginning.

    As print takes a reference, why not simplify the code and make it faster?:

    my $csv = Text::CSV->new ({ binary => 1, auto_diag => 1, eol => $/ }); open my $fh, ">:encoding(utf8)", $filename or die "$filename: $!"; $sth = $dbh->prepare ($query) or # No need to put "'s around $query error ($q, "Problem with database call"); if ($sth->execute) { # not using RaiseError? while (my $ref = $sth->fetch) { # fetching data by ref is faster $csv->print ($fh, $ref); } }

    Enjoy, Have FUN! H.Merijn
      Thanks for the insight everyone! Tux, I attempted using your code with the scalar as a reference but the csv command is specifically looking for an array reference. Am I doing something wrong?
      if($sth->execute) { while(my $dat = $sth->fetchrow) {$csv->print($fh, +$dat); }
      Expected fields to be an array ref at ./name.pl line 65. I feel as though this will only work as \@dat.

        Yes, fetchrow returns a list, fetch is an alias to fetchrow_arrayref and returns a reference.


        Enjoy, Have FUN! H.Merijn
Re: CSV EOL Question
by Eily (Monsignor) on Jan 22, 2014 at 16:02 UTC

    I have pulled up no information on what $/ means.
    You'll find that in perlvar which is where all punctuation-named variables are documented. It is the input record separator. Its default value is newline, so it is often used instead of "\n" because it needs fewer key strokes. This might not work well if the input files do not have the same format as the ouput one (for exemple an input file with line ending on "\r") and $/ was not modified with proper care (read: with local and a small enough scope).