Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ray Miller
committed
May 6, 2010
0 parents
commit 88b3c00
Showing
4 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
A handy wrapper around the Text::CSV_XS Perl module for writing CSV | ||
data, taking away some of the boilerplate code for simple usage. | ||
|
||
To write to CSV data to STDOUT: | ||
|
||
my $csv = CSV::Writer->new; | ||
$csv->write( 'foo', 'bar', 'baz' ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
name = CSV-Writer | ||
author = Ray Miller | ||
license = Perl_5 | ||
copyright_holder = Ray Miller | ||
|
||
[@Classic] | ||
|
||
[CompileTests] | ||
|
||
[AutoVersion] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
package CSV::Writer; | ||
|
||
# ABSTRACT: wrapper around Text::CSV_XS to reduce boilerplate when writing CSV files | ||
|
||
use Moose; | ||
use MooseX::Types::IO 'IO'; | ||
use Text::CSV_XS; | ||
use namespace::autoclean; | ||
|
||
has output => ( | ||
isa => 'IO', | ||
accessor => '_output', | ||
coerce => 1, | ||
default => sub { IO::Handle->new_from_fd( \*STDOUT, 'w' ) } | ||
); | ||
|
||
has csv_opts => ( | ||
is => 'ro', | ||
isa => 'HashRef', | ||
default => sub { { eol => $/ } } | ||
); | ||
|
||
has csv => ( | ||
isa => 'Text::CSV_XS', | ||
accessor => '_csv', | ||
lazy_build => 1 | ||
); | ||
|
||
has columns => ( | ||
traits => [ 'Array' ], | ||
handles => { | ||
columns => 'elements', | ||
has_columns => 'count', | ||
|
||
}, | ||
default => sub { [] }, | ||
); | ||
|
||
sub _build_csv { | ||
Text::CSV_XS->new( shift->csv_opts ); | ||
} | ||
|
||
sub write { | ||
my $self = shift; | ||
|
||
my $data; | ||
|
||
if ( @_ == 1 and ref $_[0] eq 'ARRAY' ) { | ||
$data = shift @_; | ||
} | ||
elsif ( @_ == 1 and ref $_[0] eq 'HASH' ) { | ||
confess "must specify columns when writing a hash" | ||
unless $self->has_columns; | ||
$data = [ @{ $_[0] }{ $self->columns } ]; | ||
} | ||
else { | ||
$data = \@_; | ||
} | ||
|
||
$self->_csv->print( $self->_output, $data ) | ||
or confess "Failed to write data to CSV: $!"; | ||
} | ||
|
||
1; | ||
|
||
__END__ | ||
=pod | ||
=head1 NAME | ||
CSV::Writer | ||
=head1 SYNOPSIS | ||
use CSV::Writer; | ||
my $csv = CSV::Writer->new(); | ||
$csv->write( @data ); | ||
=head1 DESCRIPTION | ||
Wrapper around Text::CSV_XS to reduce boilerplate when writing CSV files. | ||
=head1 METHODS | ||
=head2 new | ||
Constructor, accepts a hash ref or list of key/value pairs: | ||
=over 4 | ||
=item output | ||
The filename or L<IO::Handle> object that output will be written to. | ||
=item csv_opts | ||
A hash reference of options for the L<Text::CSV_XS> constructor. | ||
=back | ||
=head2 write( I<@data> ) | ||
Write I<@data> as CSV to the output stream | ||
=head1 SEE ALSO | ||
L<Text::CSV_XS>, L<Moose>, L<MooseX::Types::IO> | ||
=head1 AUTHOR | ||
Ray Miller E<lt>rm7@sanger.ac.ukE<gt> | ||
=head1 BUGS | ||
None reported...yet! | ||
=cut | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
#!/usr/bin/env perl | ||
|
||
use strict; | ||
use warnings FATAL => 'all'; | ||
|
||
use Test::Most; | ||
use File::Temp; | ||
use Readonly; | ||
|
||
Readonly my @DATA => ( | ||
[ "a", "b,c", "d", 1 ], | ||
[ "e", "f", "g", 2 ], | ||
[ "h", "i", "j", 3 ], | ||
); | ||
|
||
Readonly my $CSV => <<'EOT'; | ||
a,"b,c",d,1 | ||
e,f,g,2 | ||
h,i,j,3 | ||
EOT | ||
|
||
use_ok 'CSV::Writer'; | ||
|
||
{ | ||
ok my $csv = CSV::Writer->new(), 'no args constructor'; | ||
isa_ok $csv, 'CSV::Writer', '...the object it returns'; | ||
can_ok $csv, 'write'; | ||
can_ok $csv, '_output'; | ||
isa_ok $csv->_output, 'IO::Handle'; | ||
can_ok $csv, '_csv'; | ||
isa_ok $csv->_csv, 'Text::CSV_XS'; | ||
can_ok $csv, 'csv_opts'; | ||
isa_ok $csv->csv_opts, 'HASH'; | ||
} | ||
|
||
{ | ||
my $tmp = File::Temp->new; | ||
ok my $csv = CSV::Writer->new( output => $tmp ), 'output to tmp file'; | ||
|
||
for ( @DATA ) { | ||
ok $csv->write( $_ ), "print \[@{$_}\]"; | ||
} | ||
|
||
$tmp->seek(0,0); | ||
my $file_contents = do { local $/ = undef; $tmp->getline }; | ||
is $file_contents, $CSV, 'file contents'; | ||
} | ||
|
||
{ | ||
my $csv_str; | ||
ok my $csv = CSV::Writer->new( output => \$csv_str ), 'output to string'; | ||
for ( @DATA ) { | ||
ok $csv->write( @$_ ), "print @{$_}"; | ||
} | ||
|
||
is $csv_str, $CSV, 'string contents'; | ||
} | ||
|
||
{ | ||
my $csv_str; | ||
ok my $csv = CSV::Writer->new( output => \$csv_str, csv_opts => { eol => "\n", quote_char => q{'} } ), 'specify csv options'; | ||
for ( @DATA ) { | ||
ok $csv->write( $_ ), "write \[@{$_}\]"; | ||
} | ||
( my $expected_str = $CSV ) =~ s/"/'/g; | ||
is $csv_str, $expected_str, 'string contents'; | ||
} | ||
|
||
{ | ||
my $csv_str; | ||
ok my $csv = CSV::Writer->new( output => \$csv_str, columns => [ qw( a b d ) ] ), 'specify columns'; | ||
ok $csv->write( { a => 1, b => 2, c => 3, d => 4, e => 5 } ), 'write hashref'; | ||
is $csv_str, "1,2,4\n", 'string contents'; | ||
} | ||
|
||
{ | ||
ok my $csv = CSV::Writer->new, 'no options constructor'; | ||
throws_ok { $csv->write( { a => 1, b => 2 } ) } qr/must specify columns when writing a hash/; | ||
} | ||
|
||
done_testing(); | ||
|
||
|
||
|
||
|
||
|
||
|