Text-CSV-Simple
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/Text/CSV/Simple.pm view on Meta::CPAN
and ninth entries for each line)
=head2 field_map
$parser->field_map(qw/id name null town null postcode/);
Rather than getting back a listref for each entry in your CSV file, you
often want a hash of data with meaningful names. If you set up a field_map
giving the name you'd like for each field, then we do the right thing
for you! Fields named 'null' vanish into the ether.
=head1 TRIGGER POINTS
To enable you to make this module do things that I haven't dreamed off
(without you having to bother me with requests to extend the
functionality), we use Class::Trigger to provide a variety of points at
which you can hook in and do what you need. In general these should be
attached to the $parser object you've already created, although you
could also subclass this module and set these up as class data.
Each time we call a trigger we wrap it in an eval block. If the eval
block catches an error we simply call 'next' on the loop. These can
therefore be used for short-circuiting.on certain conditions.
=head2 before_parse
$parser->add_trigger(before_parse => sub {
my ($self, $line) = @_;
die unless $line =~ /wanted/i;
});
Before we call Text::CSV_XS 'parse' on each line of input text, we call
the before_parse trigger with that line of text.
=head2 after_parse
$parser->add_trigger(after_parse => sub {
my ($self, $data) = @_;
die unless $wanted{$data->[0]};
});
After we sucessfully call Text::CSV_XS 'parse' on each line of input text,
we call the after_parse trigger with a list ref of the values
=head2 error
Currenly, for each line that we can't parse, we call the 'failure'
trigger (with the Text::CSV_XS parser object), which emits a warning
and moves on. This happens in an invisible superclass, so you can supply
your own behaviour here:
$parser->add_trigger(on_failure => sub {
my ($self, $csv) = @_;
warn "Failed on " . $csv->error_input . "\n";
});
=cut
sub new {
my $class = shift;
return bless { _parser => Text::CSV_XS->new(@_), } => $class;
}
sub _parser { shift->{_parser} }
sub _file {
my $self = shift;
$self->{_file} = shift if @_;
return $self->{_file};
}
sub _contents {
my $self = shift;
my @lines = File::Slurp::read_file($self->_file)
or die "Can't read " . $self->_file;
return @lines;
}
sub want_fields {
my $self = shift;
if (@_) {
$self->{_wanted} = [@_];
}
return @{ $self->{_wanted} || [] };
}
sub field_map {
my $self = shift;
if (@_) {
$self->{_map} = [@_];
}
return @{ $self->{_map} || [] };
}
sub read_file {
my ($self, $file) = @_;
$self->_file($file);
my @lines = $self->_contents;
my @return;
my $csv = $self->_parser;
foreach my $line (@lines) {
eval { $self->call_trigger(before_parse => $line) };
next if $@;
next unless $line;
unless ($csv->parse($line)) {
$self->call_trigger(on_failure => $csv);
next;
}
my @fields = $csv->fields;
eval { $self->call_trigger(after_parse => \@fields) };
next if $@;
if (my @wanted = $self->want_fields) {
@fields = @fields[ $self->want_fields ];
}
my $addition = [ @fields ];
if (my @map = $self->field_map) {
my $hash = { map { $_ => shift @fields } @map };
delete $hash->{null};
$addition = $hash;
}
eval { $self->call_trigger(after_processing => $addition) };
view all matches for this distributionview release on metacpan - search on metacpan
( run in 1.347 second using v1.00-cache-2.02-grep-82fe00e-cpan-d29e8ade9f55 )