Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

introduced :strict, checking columns

  • Loading branch information...
commit 1a672bb2a8a4b931d6b0cef6179c722deec93e43 1 parent de6498a
@masak authored
Showing with 40 additions and 2 deletions.
  1. +4 −1 README
  2. +18 −1 lib/Text/CSV.pm
  3. +18 −0 t/05-strict.t
View
5 README
@@ -6,12 +6,15 @@ Simple CSV (comma-separated values) format parser for Perl 6.
say Text::CSV.read-file('somefile.csv').perl;
say Text::CSV.read("foo,bar\nbaz,boo").perl;
-Oh, and the C<read> methods take this flag:
+Oh, and the C<read> methods take the following named parameters:
:trim Removes whitespace on both ends of each value.
:skip-header Causes the first line not to be included in the output.
+ :strict Throws an error if a row has a different number of columns
+ than the previous ones.
+
:output Determines the shape of the returned data structure.
Allowed values are 'arrays' (the default), 'hashes',
and any type object (i.e. ':output(MyType)').
View
19 lib/Text/CSV.pm
@@ -16,13 +16,30 @@ class Text::CSV {
return $trim ?? $text.trim !! $text;
}
- method read($input, :$trim, :$output = 'arrays', :$skip-header) {
+ method read($input, :$trim, :$output = 'arrays', :$skip-header,
+ :$strict is copy = 'default') {
Text::CSV::File.parse($input)
or die "Sorry, cannot parse";
my @lines = $<line>;
my @values = map {
[map { extract_text($_, :$trim) }, .<value>]
}, @lines;
+ if $strict eq 'default' {
+ $strict = $output.lc ne 'arrays';
+ }
+ if $strict {
+ my $expected-columns = @values[0].elems;
+ for ^@values -> $line {
+ if (my $c = @values[$line]) > $expected-columns {
+ die "Too many columns ($c, expected $expected-columns) "
+ ~ "on line $line";
+ }
+ elsif $c < $expected-columns {
+ die "Too few columns ($c, expected $expected-columns) "
+ ~ "on line $line";
+ }
+ }
+ }
if $output.lc eq 'hashes' {
my @header = @values.shift.list;
@values = map -> @line {
View
18 t/05-strict.t
@@ -0,0 +1,18 @@
+use v6;
+use Test;
+
+use Text::CSV;
+
+my $input = q[[[one,line,four,words
+five,words,in,one,line
+only,three,words]]];
+
+lives_ok { Text::CSV.read($input) },
+ 'varying numbers of fields parse OK';
+
+dies_ok { Text::CSV.read($input, :strict) },
+ 'when strict more is on, varying numbers of fields cause an error';
+
+done_testing;
+
+# vim:ft=perl6
Please sign in to comment.
Something went wrong with that request. Please try again.