The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    Parse::CSV::Colnames - Highly flexible CSV parser including column names
    (field names) manipulation

NOTE
    This Module derives from Parse::CSV by Adam Kennedy inheriting its
    methods. The main extensions are methods for column names manipulation
    and some simple method-fixes.

SYNOPSIS
    Column names manipulation makes only sense if the fields-parameter is
    auto, i.e. column names are in the first line.

      # Parse a colon-separated variables file  from a handle as a hash
      # based on headers from the first line.
      my $objects = Parse::CSV::Colnames->new(
          handle => $io_handle,
          sep_char   => ';',
          fields     => 'auto',
       # select only rows where column name fieldname is "value"
          filter     => sub { if($_->{fieldname} eq "value") 
                           {$_} else 
                           {undef}
                            }
          );

      # get column names
      my @fn=$objects->colnames
      # you want lower case field names
      @fn=map {lc} @fn;
      # you want field names without blanks 
      @fn=map { s/\s+//g} @fn;
      # set column names
      $objects->colnames(@fn);

      while ( my $object = $objects->fetch ) {
          $object->do_something;
      }

DESCRIPTION
    This module is only an extension of Parse::CSV

    For a detailed description of all methods see Parse::CSV

    For a detailed description of the underlying csv-parser see Text::CSV_XS

Fixed METHODS
    These methods have not work in the parent module Parse::CSV yet, because
    Adam Kennedy is very busy.

  combine
      $status = $csv->combine(@columns);

    The "combine" method is passed through to the underlying Text::CSV_XS
    object. See example 3.

    It sets the fields and constructs the corresponding csv string from the
    arguments. You can read this array with the "fields" method.

  string
      $line = $csv->string;

    The "string" method is passed through to the underlying Text::CSV_XS
    object. See example 3 and example 4.

    It returns the parsed string or the corresponding combine-setting.

  print
      $status = $csv->print($io, $colref);

    The "print" method is passed through to the underlying Text::CSV_XS
    object. See example 1.

    It prints the string of the corresponding @$colref directly to an IO
    handle.

Added METHODS
  fields
      @fields = $csv->fields;

    The "fields" method is passed through to the underlying Text::CSV_XS
    object.

    It returns the input to "combine"-method or the actual row as an array.

  colnames
      @colnames = $csv->colnames("fn1","fn2") # sets colnames
                      or
      @colnames = $csv->colnames; # gets colnames

    The "colnames" method sets or gets colnames (="fields"-param). So you
    can rename the colnames (hash-keys in Parse::CSV::Colnames object).

  pushcolnames
      @colnames = $csv->pushcolnames("fn1","fn2")

    The "pushcolnames" method adds colnames at the end of $csv->colnames
    (="fields"-param). You can do that if the "filter"-method adds some new
    fields at the end of fields-array in Parse::CSV::Colnames object .
    Please consider that these colnames or fields are not in the underlying
    Text::CSV_XS object. See example 1 and example 4.

  pushcombine
      @colnames = $csv->pushcombine("fn1","fn2")

    The "pushcombine" method adds fields at the end of the actual row
    (="fields"-method) and constructs the corresponding csv string. You can
    read the result with the "fields"-method. The pushcombine and
    pushcolnames belong together. See example 4.

EXAMPLES
    You can test these examples with copy and paste

  Example 1
    Using "csv->print", "csv->pushcolnames"

      #!/usr/bin/perl 

      use strict;
      use warnings;
      use Parse::CSV::Colnames;
      my $fh=\*DATA;
      my $fhout=\*STDOUT; # only for demo
      my $csv = Parse::CSV::Colnames->new(
                             #file => "testnamen.csv",
                             handle     => $fh,
                             sep_char   => ';',
                             fields     => 'auto',
                             binary     => 1, # for german umlauts and utf
                             filter     => sub { $_->{country}="Germany"; 
                                     $_->{product}=$_->{factor1}*$_->{factor2};
                                     # select only rows where column name product>0 
                                     if($_->{product}>0) {
                                             $_;
                                     } else {
                                             undef
                                     }
                            }
                             );

      # add colnames at the end
      $csv->pushcolnames(qw(product country));
      # get column names
      my @fn=$csv->colnames;
      # you want lower case field names
      @fn=map {lc} @fn;
      # you want field names without blanks
      map { s/\s+//g} @fn;
      # set column names
      $csv->colnames(@fn);

      # headerline for direct output
      $csv->print($fhout,[$csv->colnames]); # print header-line
      print "\n";


      while(my $line=$csv->fetch) {
            # csv direct output
            $csv->print($fhout,[$csv->fields,$line->{product},$line->{country}]); # only input-fields are printed with method fields
            print "\n";
      }

      __DATA__
      Name;Given Name;factor1;factor2
      Hurtig;Hugo;5.4;4.6
      Schnallnichts;Carlo;6.4;4.6
      Weissnich;Carola;7.4;4.6
      Leer;Hinnerk;0;4.6
      Keine Ahnung;Maximilian;8.4;4.6

  Example 2
    Building new fields by hand with map

      #!/usr/bin/perl 

      use strict;
      use warnings;
      use Parse::CSV::Colnames;
      my $fh=\*DATA;
      my $csv = Parse::CSV::Colnames->new(
                             #file => "testnamen.csv",
                             handle     => $fh,
                             sep_char   => ';',
                             fields     => 'auto',
                             binary     => 1, # for german umlauts
                             filter     => sub { $_->{country}="Germany"; 
                                     $_->{product}=$_->{factor1}*$_->{factor2};
                                     # select only rows where column name product>0 
                                     if($_->{product}>0) {
                                             $_;
                                     } else {
                                             undef
                                     }
                            }
                             );
      #add new fieldname at the end
      $csv->pushcolnames(qw(product));
      # get column names
      my @fn=$csv->colnames;
      # you want lower case field names
      @fn=map {lc} @fn;
      # you want field names without blanks
      map { s/\s+//g} @fn;
      # set column names
      $csv->colnames(@fn);

      # headerline with only 2 fields
      my @outcolnames1=(qw(givenname product));
      print join(";",@outcolnames1) . "\n"; 


      while(my $line=$csv->fetch) {
            print join(";",map {$line->{$_}} @outcolnames1) . "\n"; 

      }

      __DATA__
      Name;Given Name;factor1;factor2
      Hurtig;Hugo;5.4;4.6
      Schnallnichts;Carlo;6.4;4.6
      Weissnich;Carola;7.4;4.6
      Leer;Hinnerk;0;4.6
      Keine Ahnung;Maximilian;8.4;4.6

  Example 3
    Using "csv->combine" and "csv->string"

      #!/usr/bin/perl 

      use strict;
      use warnings;
      use Parse::CSV::Colnames;
      my $fh=\*DATA;
      my $csv = Parse::CSV::Colnames->new(
                             #file => "testnamen.csv",
                             handle     => $fh,
                             sep_char   => ';',
                             fields     => 'auto',
                             binary     => 1, # for german umlauts
                             filter     => sub { $_->{country}="Germany"; 
                                     $_->{product}=$_->{factor1}*$_->{factor2};
                                     # select only rows where column name product>0 
                                     if($_->{product}>0) {
                                             $_;
                                     } else {
                                             undef
                                     }
                            }
                             );
      $csv->pushcolnames(qw(product country));
      # get column names
      my @fn=$csv->colnames;
      # you want lower case field names
      @fn=map {lc} @fn;
      # you want field names without blanks
      map { s/\s+//g} @fn;
      # set column names
      $csv->colnames(@fn);

      # headerline
      my @outcolnames2=(qw(givenname product country));
      $csv->combine(@outcolnames2);
      print $csv->string . "\n";


      while(my $line=$csv->fetch) {
            # csv output
            $csv->combine(map {$line->{$_}} @outcolnames2);
            print $csv->string . "\n";


      }


      __DATA__
      Name;Given Name;factor1;factor2
      Hurtig;Hugo;5.4;4.6
      Schnallnichts;Carlo;6.4;4.6
      Weissnich;Carola;7.4;4.6
      Leer;Hinnerk;0;4.6
      Keine Ahnung;Maximilian;8.4;4.6

  Example 4
    Using "csv->pushcombine" , "csv->pushcolnames" and "csv->string"

      #!/usr/bin/perl 

      use strict;
      use warnings;
      use Parse::CSV::Colnames;
      my $fh=\*DATA;
      my $csv = Parse::CSV::Colnames->new(
                             #file => "testnamen.csv",
                             handle     => $fh,
                             sep_char   => ';',
                             fields     => 'auto',
                             binary     => 1, # for german umlauts
                             filter     => sub { $_->{country}="Germany"; 
                                     $_->{product}=$_->{factor1}*$_->{factor2};
                                     # select only rows where column name product>0 
                                     if($_->{product}>0) {
                                             $_;
                                     } else {
                                             undef
                                     }
                            }
                             );
      $csv->pushcolnames(qw(product country));
      # get column names
      my @fn=$csv->colnames;
      # you want lower case field names
      @fn=map {lc} @fn;
      # you want field names without blanks
      map { s/\s+//g} @fn;
      # set column names
      $csv->colnames(@fn);

      # headerline
      $csv->combine($csv->colnames);
      print $csv->string . "\n";


      while(my $line=$csv->fetch) {
            # csv output
            $csv->pushcombine(map {$line->{$_}} qw(product country));
            # is like
            $csv->pushcombine($line->{product},$line->{country});
             
        print $csv->string . "\n";


      }


      __DATA__
      Name;Given Name;factor1;factor2
      Hurtig;Hugo;5.4;4.6
      Schnallnichts;Carlo;6.4;4.6
      Weissnich;Carola;7.4;4.6
      Leer;Hinnerk;0;4.6
      Keine Ahnung;Maximilian;8.4;4.6

TODO
    Creating Methods "popcolnames" and "popcombine". These methods delete
    the last fieldnames (column names) or fields. (I will add these methods
    if anybody wants this)

    Creating Methods "(un)shiftcolnames" and "(un)shiftcombine". These
    methods add/delete the first fieldnames (column names) or fields. (I
    will add these methods if anybody wants this)

    Integrating methods "getline_hr" and "column_names" of the underlying
    object Text::CSV_XS.

SUPPORT
    Bugs should always be reported via the CPAN bug tracker at

    <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Parse-CSV-Colnames>

AUTHORS
    Uwe Sarnowski <uwes at cpan.org>

    Author of the parent modul Parse::CSV : Adam Kennedy

SEE ALSO
    Parse::CSV, Text::CSV_XS

COPYRIGHT
    Copyright 2011 Uwe Sarnowski

    This program is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

    The full text of the license can be found in the LICENSE file included
    with this module.