2

If I am writing tabular output to a file as CSV, what advantage does loading an extra module Text::CSV and converting my data to an object get me over a basic loop and string manipulation? I have seen a couple of answers that suggest doing this: How can I get column names and row data in order with DBI in Perl and How do I create a CSV file using Perl.

Loading up an entire module seems like overkill and significant overhead for something I can write in four lines of Perl (ignoring data retrieval, etc.):

my $rptText = join(',', map { qq/"$_"/ } @head) . "\n";

foreach my $person ( @$data ) {
    $rptText .= join(',', map { qq/"$person->{$_}"/ } @head) . "\n";
}

So what does loading Text::CSV get me over the above code?

Borodin
  • 126,100
  • 9
  • 70
  • 144
ND Geek
  • 398
  • 6
  • 21
  • `join(',', map { qq/"$person->{$_}"/ } @head)` is better as `join(',', map { qq/"$_"/ } @{$person}{@head})` – Borodin Jul 10 '18 at 17:14

2 Answers2

7

For simple trivial data (which, admittedly, is quite common) there's no advantage. You can join , print, and go on your merry way. For a quick throw-away script that's likely all you need (and faster, too, if you'd need to consult the Text::CSV documentation).

The advantages start when your data is non-trivial.

  • Does it contain commas?
  • Does it contain double-quotes?
  • Does it contain newlines?
  • Does it contain non-ASCII characters?
  • Is there a distinction between undef (no value) and '' (empty string)?
  • Might you need to use a different separator (or let the user specify it)?

For production code, the standard pro-module advice applies:

  • Reuse instead of reinvent (particularly if you'll be generating more than one CSV file)
  • It keeps your code cleaner (more consistent and with better separation of concerns)
  • CPAN modules are often faster (better optimized), more robust (edge-case handling), and have a cleaner API than in-house solutions.
  • The overhead of loading a module is almost certainly a non-issue.
Michael Carman
  • 30,628
  • 10
  • 74
  • 122
  • 1
    Also, `Text::CSV` will, by default, use the XS module `Text::CSV_XS` as its backend, which will be substantially faster than any non-trivial Perl equivalent. – Borodin Jul 10 '18 at 16:55
5

Your CSV won't be valid if $person->{col1} contains ". Also, all columns will be wrapped in double quotes, which might not be desired (e.g. numbers). You'll also get "" for undefined values, which might not work if you plan to load the CSV into a database that makes a distinction between null and ''.

choroba
  • 231,213
  • 25
  • 204
  • 289