in reply to Open Flat File

Thanks for the post BBQ, the routine is fast and functional. But, personally, I would not use it because of the namespace pollution. If I were reading your code and did not know that %PEOPLE was dynamically defined in OpenFlatFile, it might take me a long time to figure out where it was defined. Also with your method you cant very well 'use strict'.

Here is a design I would use. It is a tiny bit slower, but you would not notice for files under 5000 lines, and if the file is a greater size, then use a database:
use strict; use Data::Dumper; my $data = OpenFlatFile("flatfile.txt", "\t"); my @PEOPLE = @{$data->{'PEOPLE'}}; my @CAR_COLORS = @{$data->{'CAR_COLORS'}}; my @CARS = @{$data->{'CARS'}}; my @AGES = @{$data->{'AGES'}}; for(my $i=0; $i < $data->{'ROWCOUNT'}; $i++) { print "$PEOPLE[$i] drives a $CAR_COLORS[$i] $CARS[$i] "; print "and is $AGES[$i] years old.\n" } print Data::Dumper->Dump([$data]), "\n"; sub OpenFlatFile { my ($datafile, $delimeter) = @_; open(FILE,$datafile) or return {}; chomp (my @tmp = <FILE>); close FILE; my @headers = split /\Q$delimeter\E/, shift @tmp; my $data = {}; $data->{'HEADERS'} = [@headers]; $data->{'ROWCOUNT'} = scalar(@tmp); $data->{'COLCOUNT'} = scalar(@headers); foreach my $line (@tmp) { my @a = split /\Q$delimeter\E/o, $line; push @{$$data{$_}}, shift @a foreach (@headers); } return $data; }
This code is basically the same as yours, but It creates only one variable to encapsulate the data. For my data stucture I chose to implement a hash of arrays to easily preserver the file order, but you could implement a hash or hashes unsing the first row as the second hash keys. The downside of this approach is that the code becomes a tad more verbose, but for me the verbosity adds clarity, which is far more valueable in my opinion.

For a tidbit of clarity this is what the Data::Dumper produces:
$VAR1 = { 'AGES' => [ 26, 25, 50 ], 'CARS' => [ 'Volks', 'Fiat (yuck)', 'Twingo' ], 'ROWCOUNT' => 3, 'HEADERS' => [ 'PEOPLE', 'CARS', 'CAR_COLORS', 'AGES' ], 'PEOPLE' => [ 'John', 'Mira', 'Mom' ], 'CAR_COLORS' => [ 'avocado', 'black', 'cherry' ], 'COLCOUNT' => 4 };

Replies are listed 'Best First'.
RE: RE: Open Flat File
by BBQ (Curate) on May 08, 2000 at 18:51 UTC
    Wow! That is so cool! I've always wanted to put in a rownumber variable in there somewhere, but I the approach that I had thought of was by generating a $ROWNUM{$key} variable.

    About the namespace littering, that has always been one of my concerns, but I've noticed that it is very hard to be flexible if you don't allow the variables to be "public". You see, one of the reasons why I was never running this sub under strict, was because I had it maintaining a forum, and some of the file headers got dynamically allocated depending on the posters UID, message ID, etc. By using strict, I couldn't flood the process with hashes that I didn't know the name for before hand and that made my code impossible to run. It gets complicated if you know that one of your tables contains a hash of the headers used in other tables.

    I've never managed to overcome that, but I would like to (maybe by moving everything out of main::(?)). Maybe someday when I have free time, I'll look into it just for the hell of it. Nowadays I'm using DBMSs, so I don't worry about it that much.

    Thanks for the facelift!
Re: RE: Open Flat File
by Anonymous Monk on Sep 07, 2001 at 02:19 UTC
    Wow. What a find. Fits my application perfectly for tracking a few dozen things in a table.

    Now, I've tried several versions of a SaveFlatFile sub, but this being my first try at references, it just doesn't click/work. Can someone help me here? Pretty please with perl on top??

    Thanks, Doug