The Case for Simplicity

Part of my design goal for Tie::Array::CSV was to be an elegant blend of tied objects making hard things easy both at the user and author (me) levels.

A few months back I announced that Tie::Array::CSV is now more efficient on row ops. Since then I have had a nagging thought; this change cost me elegance and simplicity.

To implement the deferred row operations, I made my row objects wait until their destructor to update the file. Sounds nice until you realize that you now have race conditions all over the place. So you hunt them down and store/update more internal data, always keeping track of what has been changed. A simple change became a big undertaking. As the project finished I couldn’t help but yearn for the simplicity of the original design goal.

Yesterday, in this staring match with myself, I finally blinked. I retrieved the old code, merged in a few of the newer niceties that I wanted to keep and moved the more convoluted deferred-row-op logic into a subclass.

Here I announce the release of Tie::Array::CSV version 0.05; featuring simplicity in the base class and deferred row operations in a subclass.

Its not the most efficient (read: fast) way to read CSV files and it doesn’t handle embedded newlines, but if you just want to act on a CSV file like a 2D Perl array (i.e. array of array references), give it a try.

Fork Tie::Array::CSV on GitHub

PS. Mithaldu, you can now pass a Text::CSV object (or subclass) to the constructor if you would like :)

6 Comments

Hi Joel

But why use tie anyway? Here’s how I do it:

sub read_csv_file
{
my($self, $file_name) = @_;
my($csv) = Text::CSV_XS -> new({allow_whitespace => 1});
my($io)  = IO::File -> new($file_name, 'r');

$csv -> column_names($csv -> getline($io) );

return $csv -> getline_hr_all($io);

} # End of read_csv_file.

So, it returns an arrayref of hashrefs.

And with a file of 2 cols, ‘type’ and ‘value’, use that sub like:

for my $record (@{$self -> utils -> read_csv_file($self -> lexed_file)})
{
$obj -> read($$record{type}, $$record{value});
}

And sorry but no - not interested in arguments about memory usage or speed. /That’s simplicity!/

Cheers Ron

Hi Joel

I’m pretty sure I do understand. The difference is precisely as you’ve stated: I end up with a hashref per line (i.e. the Perl way), and you end up with an array…

Cheers Ron

my($self, $file_name) = @_;

LOL. Discarding the first argument to your function makes it “object-oriented,” and therefore “good.”

Leave a comment

About Joel Berger

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