Parse-CSV

 view release on metacpan or  search on metacpan

lib/Parse/CSV.pm  view on Meta::CPAN


=head2 new

The C<new> constructor creates and initialises a new CSV parser.  It
returns a new L<Parse::CSV> object, or throws an exception (dies) on
error.  It accepts a number of params:

=over 4

=item C<file>

=item C<handle>

To specify the CSV data source, provide either the C<file>
param, which should be the name of the file to read, or the C<handle>
param, which should be a file handle to read instead.

=item C<csv_attr>

Any parameter for L<Text::CSV_XS>'s constructor can also be provided
to this C<new> method, and they will be passed on to it.
Alternatively, they can be passed as a single C<HASH> reference as the
C<csv_attr> param. For example:

  $parser = Parse::CSV->new(
      file     => 'file.csv',
      csv_attr => {
          sep_char   => ';',
          quote_char => "'",
      },
  );

=item C<names>

An optional C<names> param can be provided, which should either be an
array reference containing the names of the columns:

  $parser = Parse::CSV->new(
      file  => 'file.csv',
      names => [ 'col1', 'col2', 'col3' ],
  );

or a true value that's not a reference, indicating that the column
names will be read from the first line of the input:

  $parser = Parse::CSV->new(
      file  => 'file.csv',
      names => 1,
  );

If the C<names> param is provided, the parser will map each line to a
hash where the keys are the field names provided, and the values are the
values found in the CSV file.

If the C<names> param is B<not> provided, the parser will return simple
array references of the columns, treating them just like all the other
rows in the file.

If your CSV file has (or might have) a <Byte-Order Mark|https://en.wikipedia.org/wiki/Byte_order_mark>,
you must use the C<names> functionality, because this lets us call the C<header>
method of C<Text::CSV_XS>, which is the only place the BOM is handled
in that module.

=item C<filter>

The optional C<filter> param will be used to filter the records if
provided. It should be a C<CODE> reference or any otherwise callable
scalar, and each value parsed (either array reference or hash reference)
will be available to the filter as C<$_> to be changed or converted into an object,
or whatever you wish.  See the L</Writing Filters> section for more details.

=back

=cut

sub new {
	my $class = shift;
	my $self  = bless {
		@_,
		row    => 0,
		errstr => '',
	}, $class;

	# Do we have a file name
	if ( exists $self->{file} ) {
		unless ( Params::Util::_STRING($self->{file}) ) {
			Carp::croak("Parse::CSV file param is not a string");
		}
		unless ( -f $self->{file} and -r _ ) {
			Carp::croak("Parse::CSV file '$self->{file}' does not exist");
		}

		$self->{handle} = IO::File->new();
		unless ( $self->{handle}->open($self->{file}) ) {
			Carp::croak("Parse::CSV file '$self->{file}' failed to load: $!");
		}
	}

	# Do we have a file handle
	if ( exists $self->{handle} ) {
		unless ( Params::Util::_HANDLE($self->{handle}) ) {
			Carp::croak("Parse::CSV handle param is not an IO handle");
		}
	} else {
		Carp::croak("Parse::CSV not provided a file or handle param");
	}

	# Separate the Text::CSV attributes
	unless ( Params::Util::_HASH0($self->{csv_attr}) ) {
		$self->{csv_attr} = {binary => 1};  # Suggested by Text::CSV_XS docs to always be on
		# XXX it would be nice to not have this list hard-coded.
		foreach ( qw{quote_char eol escape_char sep_char binary always_quote} ) {
			next unless exists $self->{$_};
			$self->{csv_attr}->{$_} = delete $self->{$_};
		}
	}

	# Create the parser
	$self->{csv_xs} = Text::CSV_XS->new( $self->{csv_attr} );
	unless ( $self->{csv_xs} ) {
		Carp::croak("Failed to create Text::CSV_XS parser");



( run in 3.687 seconds using v1.01-cache-2.11-cpan-2398b32b56e )