A Case for Tie::Array::CSV

What is the favorite module you have released to CPAN? For me, its not some shiny CMS or fancy scientific simulation. In fact, mine is probably horribly inefficient, maybe even a little evil, but I like this one best because it is clever.

Today I used my favorite of my modules in order to accomplish a difficult task, and in doing so I found a little bug, which I have just fixed. Which one is it? Let me introduce you to Tie::Array::CSV.

Tie::Array::CSV lets you treat a CSV (or any other deliminated file that Text::CSV can handle) as a Perl array of arrayrefs. It lets you read and write just as you would any other AoA, but in the background you are CRUD-ing a csv file.

Today I needed to write columns to a CSV file, in order to pass them to Gnuplot. Normally I would use PDL for this, but the columns are of uneven length, and while I’m sure there is some way to do this, I don’t know what it is. The problem of course is that if column three is longer than column two, you will need to put an empty entry in column two so that they line up correctly. Luckily I have Tie::Array::CSV.

For this example I make a little function that generates a list of random data of random length. I want to write this data as the next column in my CSV file. Lets say I want to do this 10 times making 10 columns. Here it is:

#!/usr/bin/env perl

use strict;
use warnings;

use Tie::Array::CSV;

sub get_column {
  my $last = int rand 10;
  return map { rand 100 } (0..$last);
}

tie my @out, 'Tie::Array::CSV', 'outfile.csv';

for my $column (0..9) {
  my $row = 0;
  $out[$row++][$column] = $_ for get_column();
}

See? Piece of cake! Notice the “ragged” bottom few lines, that’s the hard part, but I didn’t have to think about it at all!

I hope if you need to work with CSV data, you’ll think about using Tie::Array::CSV. Its probably not the fastest, but I think its the easiest and most self-explanatory. Oh and if the tie keyword scares you, there is also a new constructor.

Now what is your favorite module? Is it the most clever one, the most useful? Let me know!

6 Comments

This is a great idea for a blog post. And really a pretty neat idea for a module too. And in the spirit of your request, mine is Ouch. It’s a simple exception handler, like Exception::Class, but without all the verbosity.

I use Tie::Array::CSV all the time. It’s one of my can’t-live-without modules. Thanks for producing and maintaining it.

I always use tied arrays and hashes where possible. My other favourites are Tie::StoredOrderHash, Tie::Array::DBD and, of course, Tie::File.

Hi Joel, Thanks for providing Tie::Array::CSV module. I’m starting to use it and hope to get a better hold of it. I’m using Mac, running Perl v5.12.3

The example you provide here works for me well, outputting the outfile.csv file.

By amending the code to : tie my @file, ‘Tie::Array::CSV’, ‘outfile.csv’; print $file[1][0]; I am able to read from the outfile.csv as well!

My problem starts when I make an attempt to open outfile.csv in Excel, make some value changes, and then save it again as CSV format (i tried all possible csv format that Excel 2011 (for Mac) v14.3.2 supports). All my attempts to then read from the newly saved CSV file (or any other csv files that I have) - all failed. The Tie:Array:CSV simply ignore these files. By opening the original outfile.csv and the one that was re-saved by Excel in Text editor I do notice some differences.

What would be the best way to read csv files that were generated by Excel? Alternatively is there any recommended file conversion I should include?

Thanks a million, Roy

Leave a comment

About Joel Berger

user-pic As I delve into the deeper Perl magic I like to share what I can.