6

I may be missing something obvious, but I have a very simple perl script in which the is_quoted() method in the Text::CSV module is not working as expected. Here's the code:

# cat ./testcsv.pl
#!/usr/bin/perl

use strict;
use Text::CSV;

my $csv = Text::CSV->new ( { quote_char => '"' } )
        or die "Cannot use CSV: ".Text::CSV->error_diag ();

print "Text::CSV version = " . $csv->version() . "\n\n";

my $line = '"text field 111",222,"text field 333",444';

my $status  = $csv->parse($line);
if ($status)
  {
  my $column_idx = 0;
  my @fields = $csv->fields ();
  foreach my $field (@fields)
     {
     my $quoted = $csv->is_quoted ($column_idx);
     $column_idx++;
     print "field #$column_idx: '$field'; quoted = " . ($quoted ? "YES\n" : "NO\n");
     }
  }

And here's what I get when I run the script:

    # perl -v  | grep "is perl"
    This is perl, v5.10.1 (*) built for PA-RISC2.0
    # ./testcsv.pl
    Text::CSV version = 1.29

    field #1: 'text field 111'; quoted = NO
    field #2: '222'; quoted = NO
    field #3: 'text field 333'; quoted = NO
    field #4: '444'; quoted = NO
    # 

As we can see, the parse() method is correctly separating the original string into fields, so I know that Text::CSV is installed and working correctly. It was my understanding from reading the documentation for Text::CSV that the is_quoted() method is supposed to return a true value if the data in the indicated column is enclosed in quote_char quotes. Therefore I was expecting to see 'YES' after fields 1 & 3, as they're clearly quoted in the initialization for the $line variable. But this is not happening.

Am I doing something wrong, or is Text::CSV broken?

barush
  • 303
  • 2
  • 6

1 Answers1

7

You need to specify keep_meta_info => 1.


By the way, I dislike having two iterators, so I'd iterate over the indexes.

my @fields = $csv->fields();
for my $column_idx (0..$#fields) {
   my $field = $fields[$column_idx];
   ...
}
ikegami
  • 367,544
  • 15
  • 269
  • 518
  • Duh. Thanks. That's the correct answer. Thanks very much for answering so quickly, and sorry for the waste of bandwidth! (I would vote you up but don't have sufficient reputation to do so.) – barush Jan 07 '13 at 22:30
  • 1
    The answer wasn't obvious to me either. It should be mentioned in the docs for `is_quoted`. I looked up the test file for it, though I later noticed the example in the Synopsis also uses `keep_meta_info`. – ikegami Jan 07 '13 at 22:37
  • I agree with your comment about using only one iterator; in that case, however, the iterator range would be: `(0..$#fields - 1)` – barush Jan 07 '13 at 23:07
  • @barush - No, ikegami is correct. $#fields returns the last index of, not the # of elements in, the array. – runrig Jan 07 '13 at 23:17
  • 1
    @barush, `0..$#fields` or `0..@fields-1`, but no, not `0..$#fields-1` – ikegami Jan 08 '13 at 00:37
  • Regarding the non-obvious answer (`keep_meta_info =>1`), is there some formal mechanism by which one might request that the Text::CSV module's authors update the documentation for the `is_quoted()` method (and for any others affected by `keep_meta_info`)? – barush Jan 08 '13 at 17:18
  • Go to the [distro](http://search.cpan.org/dist/Text-CSV/) on CPAN and click "View/Report bugs" – ikegami Jan 08 '13 at 18:39