### ----------------------------------------------------
### -- Text::CSV
### -- Licenses: Artistic-2.0
### -- Authors: H.Merijn Brand (Tux)
### -- File: doc/Text-CSV.md
### ----------------------------------------------------
### -- Chunk 2 of 3
 passed as a string, the syntax of the range is as
defined by [RFC7111](#fragment) and thus 1-based.

## rowrange


    $csv.rowrange("1;16-*");
    my @r = $csv.rowrange;

Set or inspect the row ranges. Only supports [RFC7111](#fragment) style.
Indexes are 1-based.

## column\_names
=head2 column-names



Set the "keys" that will be used in the ["getline\_hr"](#getline_hr) calls. If no keys
(column names) are passed, it will return the current setting as a list.

    $csv.column_names(< code description price >);
    my @names = $csv.column_names;

["column\_names"](#column_names) accepts a list of strings (the column names) or a single
array with the names. You can pass the return value from ["getline"](#getline) too:

    $csv.column_names($csv.getline($io));

["column\_names"](#column_names) does **no** checking on duplicates at all, which might lead
to unexpected results. As raku does not accept undefined keys in a hash,
passing just types will lead to fail later on.

    $csv.column_names(Str, "", "name"); # Will FAIL becaus of Str
    $csv.column_names(< code name count name >); # will drop the second column
    %hr = $csv.getline_hr($io);

## header

Parse the CSV header and set `sep` and encoding.

    my @hdr = $csv.header($fh).column-names;
    $csv.header($fh, sep-set => [ ";", ",", "|", "\t" ]);
    $csv.header($fh, munge-column-names => "fc");

The first argument should be a file handle.

Assuming that the file opened for parsing has a header, and the header does
not contain problematic characters like embedded newlines, read the first
line from the open handle then auto-detect whether the header separates the
column names with a character from the allowed separator list.

If any of the allowed separators matches, and none of the _other_ allowed
separators match, set [`sep`](#sep) to that separator for the current
CSV\_XS instance and use it to parse the first line, map those to lowercase,
and use that to set the instance ["column\_names"](#column_names):

    my $csv = Text::CSV.new;
    my $fh = open "file.csv";
    $csv.header($fh);
    while (my $row = $csv.getline_hr($fh)) {
        ...
        }

If the header is empty, contains more than one unique separator out of the
allowed set, contains empty fields, or contains identical fields (after
folding), it will croak with error 1010, 1011, 1012, or 1013 respectively.

If the header contains embedded newlines or is not valid CSV in any other
way, this method will throw an exception.

A successful call to `header` will always set the [`sep`](#sep) of the
`$csv` object. This behavior can not be disabled.

### return value

On error this method will throw an exception.

On success, this method will return the instance.

### Options

- sep-set

        $csv.header($fh, sep_set => [ ";", ",", "|", "\t" ]);

    The list of legal separators defaults to `[ ";", "," ]` and can be changed
    by this option.

    Multi-byte sequences are allowed, both multi-character and Unicode. See
    [`sep`](#sep).

- munge-column-names

    This option offers the means to modify the column names into something that
    is most useful to the application. The default is to map all column names
    to fold case.

        $csv.header($fh, munge-column-names => "lc");

    The following values are available:

         fc   - fold case
         lc   - lower case
         uc   - upper case
         none - do not change
         &cb  - supply a callback

        $csv.header($fh, munge-column-names => { "column_".$col++ });

- set-column-names

        $csv.header($fh, :set-column-names);

    The default is to set the instances column names using ["column\_names"](#column_names) if
    the method is successful, so subsequent calls to ["getline\_hr"](#getline_hr) can return
    a hash. Disable setting the header can be forced using a false value for
    this option like `:!set-column-names`.

## bind\_columns
=head2 bind-columns



NYI!

Takes a list of scalar references to be used for output with ["print"](#print) or
to store in the fields fetched by ["getline"](#getline). When you do not pass enough
references to store the fetched fields in, ["getline"](#getline) will fail with error
`3006`. If you pass more than there are fields to return, the content of
the remaining references is left untouched.

    $csv.bind_columns(\$code, \$name, \$price, \$description);
    while ($csv.getline($io)) {
        print "The price of a $name is \x[20ac] $price\n";
        }

To reset or clear all column binding, call ["bind\_columns"](#bind_columns) with the single
undefined argument like `Array`. This will also clear column names.

    $csv.bind_columns(Array);

If no arguments are passed at all, ["bind\_columns"](#bind_columns) will return the list of
current bindings or `Array` if no binds are active.

## eof


    $eof = $csv.eof;

If ["parse"](#parse) or ["getline"](#getline) was used with an IO stream, this method will
return `True` if the last call hit end of file, otherwise it will return
`False`. This is useful to see the difference between a failure and end
of file.

If the last ["parse"](#parse) or ["getline"](#getline) finished just before end of file, the
**next** ["parse"](#parse) or ["getline"](#getline) will fail and set `eof`.

That implies that if you are _not_ using ["auto-diag"](#auto-diag), an idiom like

    while (my @row = $csv.getline ($fh)) {
        # ...
        }
    $csv.eof or $csv.error_diag;

will _not_ report the error. You would have to change that to

    while (my @row = $csv.getline ($fh)) {
        # ...
        }
    $csv.error_diag.error and $csv.error_diag;

## types


NYI!

    $csv.types(@types);
    my @types = $csv.types;

This method is used to force a type for all fields in a column. For
example, if you have an integer column, two columns with doubles and a
string column, then you might do a

    $csv.types(Int, Num, Num, Str);

You can unset column types by doing a

    $csv.types(Array);

## row


    CSV::Row $row = $csv.row;

Returns the last row parsed. See [`CSV::Row`](#csv-row)

## fields


    CSV::Field @fields = $csv.fields;

This method returns the input to ["combine"](#combine) or the resultant decomposed
fields of a successful ["parse"](#parse) or ["getline"](#getline), whichever was called more
recently. The fields are still of type [`CSV::Field`](#csv-field) and
thus feature attributes.

## strings


    @fields = $csv.strings;

This method returns the input to ["combine"](#combine) or the resultant decomposed
fields of a successful ["parse"](#parse) or ["getline"](#getline), whichever was called more
recently. The fields are simplified to Str entries from
[`CSV::Field`](#csv-field), so no attributes ate available.

NYI: If types are used, the fields should comply to the types.

## meta\_info


## meta-info


    $csv.meta_info(True);
    my $km = $csv.keep_meta;

This methods sets or inquires the default setting for keeping meta-info on
fields. See [`CSV::Field`](#csv-field).

## is\_quoted


## is-quoted


    my $quoted = $csv.is_quoted($column_idx);

Where `$column_idx` is the (zero-based) index of the column in the last
result of ["parse"](#parse) or ["getline"](#getline), even if `meta` was false on that last
invocation.

This returns `True` if the data in the indicated column was enclosed in
[`quote_char`](#quote_char) quotes. This might be important for fields
where content `,20070108,` is to be treated as a numeric value, and where
`,"20070108",` is explicitly marked as character string data.

Also see [`CSV::Field`](#csv-field).

## is\_binary


## is-binary


NYI/WIP: utf8-c8

    my $binary = $csv.is_binary($column_idx);

Where `$column_idx` is the (zero-based) index of the column in the last
result of ["parse"](#parse) or ["getline"](#getline), even if `meta` was false on that last
invocation.

Also see [`CSV::Field`](#csv-field).

## is\_missing


## is-missing


NYI

    my $missing = $csv.is_missing($column_idx);

Where `$column_idx` is the (zero-based) index of the column in the last
result of ["parse"](#parse) or ["getline"](#getline), even if `meta` was false on that last
invocation.

    while (my @row = $csv.getline_hr($fh, :meta)) {
        $csv.is_missing(0) and next; # This was an empty line
        }

When using ["getline\_hr"](#getline_hr), it is impossible to tell if the parsed fields
are undefined because they where not filled in the `CSV` stream or because
they were not read at all, as **all** the fields defined by ["column\_names"](#column_names)
are set in the hash-ref. If you still need to know if all fields in each
row are provided, you should enable [`keep_meta`](#keep_meta) so you can
check the flags.

## status


    $status = $csv.status;

This method returns success (or failure) of the last invoked ["combine"](#combine) or
["parse"](#parse) call.

## error\_input


## error-input


    $bad_argument = $csv.error_input;

This method returns the erroneous argument (if it exists) of ["combine"](#combine),
["parse"](#parse), or ["getline"](#getline), whichever was called most recent. If the last
invocation was successful, `error_input` will return `Str`.

# DIAGNOSTICS

Errors are transported internally using the [`CSV::Diag`](#csv-diag)
class.  Text::CSV will return that object when it fails, so it can be
caught, but on non-fatal failures, like parse returning `False`, one can
use the methods to inquire the internal status.

## CSV::Diag

The method is created with the widest possible use in mind, serving both
the mindset of raku as well as the direct approach of the old module. It
is immutable: it is created with all available error parameters known at
the time of failure, and the cannot be changed afterwards.

    my CSV::Diag $d .= new(
        error   => 0,
        message => "",
        pos     => 0,
        field   => 0,
        record  => 0,
        buffer  => Str
        );

If only `error` is given, the message is set accordingly if it is a known
error value.

The object can be used in many contexts:

- void context

        CSV::Diag.new(error => 2034, buffer => q{ "",}, pos => 1);

    will print

        EIF - Loose unescaped quote : error 2034 @ record 1, field 1, position 2
         "?",

    which is what happens when [`auto_diag`](#auto_diag) is `True` and you
    parse illegal CSV:

        Text::CSV.new(:auto_diag).parse(q{ "",});'
        EIF - Loose unescaped quote : error 2034 @ record 1, field 1, position 2
         "?",

- numeric context

    Will return the error code

        my Int $e;
        {   fail CSV::Diag(error => 2034);
            CATCH { default { $e = +$_; }}
            }
        # $e is now 2034

- string context

    Will return the error message

        my Str $e;
        {   fail CSV::Diag(error => 2034);
            CATCH { default { $e = ~$_; }}
            }
        # $e is now "EIF - Loose unescaped quote"

- list context

    All of the 6 items can be retrieved as a list or positional:

        {   fail CSV::Diag(error => 2034);
            CATCH { default { $_[0].say; }}
            }

    The indices are chosen to be compatible with the old API

        $e[0] = error number
        $e[1] = error message
        $e[2] = error position in buffer
        $e[3] = field number
        $e[4] = record number
        $e[5] = errror buffer

- hash context

    All of the 6 items can be retrieved as a hash entry

        {   fail CSV::Diag(error => 2034);
            CATCH { default { $_<errno>.say; }}
            }

    The keys are chosen to be compatible with the old API.

        $e<errno>  = error number
        $e<error>  = error message
        $e<pos>    = error position in buffer
        $e<field>  = field number
        $e<recno>  = record number
        $e<buffer> = errror buffer

The CSV::Diag is also used by this Text::CSV method

## error\_diag


## error-diag


    $csv.error_diag;
    $error_code = +$csv.error_diag;
    $error_str  = ~$csv.error_diag;
    ($cde, $str, $pos, $rec, $fld) = $csv.error_diag;

This function returns the diagnostics of the most recent error.

If called in void context, this will print the internal error code and the
associated error message along with the record number, the position of the
failure and the buffer of failure with an eject symbol at that position:

    $csv.parse(q{ "",})
    $csv.error_diag;

will print

    EIF - Loose unescaped quote : error 2034 @ record 1, field 1, position 2
     "?",

If called in list context, this will return the error code, the error
message, the location within the line that was being parsed, the record
number, and the buffer itself in that order. Their values are 1-based. The
position currently is index of the character at which the parsing failed in
the current record. The record number the index of the record parsed by the
csv instance. The field number is the index of the field the parser thinks
it is currently trying to parse.

If called as `+$csv.error_diag` or `$csv.error_diag.Num`, it will return
the error code. If called as `~$csv.error_diag` or `$csv.error_diag.Str`
it will return the error message.

## record\_number


    $recno = $csv.record_number;

Returns the records parsed by this csv instance. This value should be more
accurate than `$.` when embedded newlines come in play. Records written by
this instance are not counted.

## set\_diag


    $csv.set_diag(0);
    $csv.set_diag(2025, pos => 12, fieldno => 4, recno => 99);

Use to (re)set the diagnostics if you are dealing with errors.

# CSV::Field

The fields are internally represented as CSV::Field objects. Any methods
that directly or indirectly supports the `meta` attribute controls
weather the returned fields will be of this CSV::Field type or that the
fields are simplified to a simple basic type.

If the fields are represented/returned as CSV::Field, it supports these
methods:

## new

    my CSV::Field $f .= new;
    my $f = CSV::Field.new("foo");
    my $f = CSV::Field.new(1);

Instantiate a new field. Optionally takes a `Cool`.

## Bool

    ?$f     and say "The field is true";
    $f.Bool and say "This field is true too";

Return the boolean value of the field. As CSV is text-only be design, this
will also return `False` for `"0"`, where raku sees `"0"` as `True`.

## text
=head2 Str

    $str = ~$f;
    $str = $f.Str;
    $str = $f.text;

Return the string representation of the field.

## Buf

    $buf = $f.Buf;

Return the field data as "utf8-c8" encoded Buf.

## Numeric

    $i = +$f;
    $i = $f.Int;
    $i = $f.Num;

Return the numeric representation of the field.

## gist

    $f.gist.say;

Will show a complete compressed representation of the field with properties.
`Q` is quoted, `q` is unquoted. Likewise for `B/b` for binary, `8/7`
for Unicode-ness and `M/m` for missing.

A field that was parsed as `,cat,` would return

    qb7m:"cat"

A field parsed as `,"Ħēłĺº",` would return

    QB8m:"Ħēłĺº"

## add

    $f.add($str);

Accepts a Str to be added to this field.

## set\_quoted

    $f.set_quoted;

Set the fact the the field was/is quoted.

## is\_quoted

    $f.is_quoted and say "The field was quoted in CSV";

Is `True` when the parsed field was quoted in the source.

## undefined

    $f.undefined and say "The field is undefined";

Returns `True` when the field is undefined. As CSV is all about strings,
the various options that allow interpreting empty fields as undefined make
this a required method.

## is\_binary

WIP: utf8-c8

    $f.is_binary and say "Do we need a Buf instead?";

Returns true if the field has data beyond ASCII.

## is\_utf8

    $f.is_utf8 or say "The field is empty or pure ACII";

Returns `True` if the field is beyond ASCII, but still valid UTF-8.

## is\_missing

WIP

    $f.is_missing and fail;

Returns `True` if the field is missing.

# CSV::Row


This class is a wrapper over the current row of fields just to add
convenience methods.

This is the only argument to callbacks.

The fields in `CSV::Row` are always of class [`CSV::Field`](#csv-field)
and thus contain all meta-information, even if the `Text::CSV` attribute
[`meta_info`](#meta_info) is `False`.

## methods

- new

        my CSV::Row $row .= new;
        my CSV::Row $row .= new(csv => $csv, fields => @f.map({ CSV::Field.new(*) });

- csv

    The current Text::CSV object related to this row.

- elems

    Return the number of fields in the row.

- fields

    The fields (CSV::Field items) this row consist of.

- push

        $row.push(CSV::Field.new(1));
        $row.push(1);
        $row.push("foo");
        $row.push($another-row);

    Pushing simple things onto the row will extend the row by converting these
    to CSV::Field objects.

    Pushing a CSV::Row onto the row will extend that row with the fields of the
    row being pushed.

- pop

        my CSV::Field $f = $row.pop;

- Str

        my $str = $row.Str;
        $io.say(~$row);

    The stringification of the CSV::Row object is like invoking the
    [`string`](#string) method. This only works if there is a Text::CSV
    object known to the CSV::Row instance.

- hash

        my %h = $row.hash;

    Returns the hash with `.csv`'s [`column_names`](#column_names) as keys
    and the `.text` of each matching `fields` entry as values.

- strings

        my @l = $row.strings;

    Returns the `.text` part of each entry in `.fields`.

The row allow direct indexing and iteration as well as hash addressing when
["column\_names"](#column_names) are set.

    my $field = $row[1];
    my $field = $row<foo>;

The last parsed row of a [Text::CSV](https://metacpan.org/pod/Text%3A%3ACSV)|/Text::CSV> can be acquired using

    my CSV::Row $row = $csv.row;

\################################################################################

# FUNCTIONS

## csv


This is an high-level function that aims at simple (user) interfaces. This
can be used to read/parse a `CSV` file or stream (the default behavior) or
to produce a file or write to a stream (define the `out` attribute). It
returns an array- or hash-reference on parsing or the
numeric value of ["error\_diag"](#error_diag) on writing. When this function fails you
can get to the error using the class call to ["error\_diag"](#error_diag)

    my $aoa = csv(in => "test.csv") or
        die Text::CSV.error_diag;

This function takes the arguments as key-value pairs. This can be passed as
a list or as an anonymous hash:

    my $aoa = csv(in => "test.csv", sep => ";");
    my $aoh = csv(in => $fh, :headers);

The arguments passed consist of two parts: the arguments to ["csv"](#csv) itself
and the optional attributes to the `CSV` object used inside the function
as enumerated and explained in ["new"](#new).

If not overridden, the default option used for CSV is

    auto_diag => 1

The option that is always set and cannot be altered is

    binary    => 1

### in


Used to specify the source. `in` can be a file name (e.g. `"file.csv"`),
which will be opened for reading and closed when finished, a file handle
(e.g. `$fh` or `FH`), a reference to a glob (e.g. `\*ARGV`), the glob
itself (e.g. `*STDIN`), or a reference to a scalar (e.g. `\q{1,2,"csv"}`).

When used with ["out"](#out), `in` should be a reference to a CSV structure (AoA
or AoH) or a Callable (Sub, Routine, Code, or Block) that returns an
array-reference or a hash-reference.  The code-ref will be invoked with no
arguments.

    my $aoa = csv(in => "file.csv");

    open my $fh, "<", "file.csv";
    my $aoa = csv(in => $fh);

    my $csv = [[qw( Foo Bar )], [ 1, 2 ], [ 2, 3 ]];
    my $err = csv(in => $csv, out => "file.csv");

The `in` attribute supports a wide range of types, all of which can be
combined with the use of `fragment`:

- Str

        csv(in => "file.csv")

    A plain string is interpreted as a file name to be opened for parsing.

- IO

        my $io = open "file.csv", :r;
        csv(in => $io);

    Parse from the already opened data stream.

- Capture

        csv(in => \("str,ing"));

    Parse from a single string.

- Array of Strings

        csv(in => ["a,b\n1,2\n3,4\n"]);
        csv(in => ["a,b", "1,2", "3,4"]);

    Parse from the String(s)

- Array of Data

        csv(in => [[<a b>], [1, 2], [3, 4]]);
        csv(in => [{:a(1), :b(2)}, {:a(3), :b(4)}]);

    Use the data as provided

- Sub, Routine

        sub provider {
            @data.elems == 0 and return False;
            return @data.pop;
            }
        csv(in => &provider);

    While the providing Routine returns a data row, use that as is. Stop when
    the provider returns `False`.

- Callable, Block

        csv(in => { $sth.fetch });

    While the providing Callable returns a data row, use that as is. Stop when
    the provider returns `False`.

- Supply

        my $supply = Supply.from-list(@data);
        csv(in => $supply);

    Fetch data rows from the supply.

- Channel

        my $ch = Channel.new;
        start {
            $ch.send($_) for @data;
            $ch.close;
            }
        csv(in => $ch);

    Fetch data from the Channel.

- Iterator

        csv(in => @data.iterator);

    Fetch data rows from the iterator.

- Any

        csv(in => Any);

    is a shortcut/fallback for

        csv(in => $*IN);

### out


In output mode, the default CSV options when producing CSV are

    eol    => "\r\n"

The ["fragment"](#fragment) attribute is ignored in output mode.

`out` can be a file name (e.g. `"file.csv"`), which will be opened for
writing and closed when finished, a file handle (e.g. `$fh` or
`IO::Handle`), a `Channel`, a `Supply`, a `Callable`, or `Nil`.

    csv(in => sub { $sth.fetch },        out => "dump.csv");
    csv(in => { $sth.fetchrow_hashref }, out => "dump.csv",
         headers => $sth.{NAME_lc});

When a code-ref is used for `in`, the output is generated per invocation,
so no buffering is involved. This implies that there is no size restriction
on the number of records. The `csv` function ends when the coderef returns
`False`.

When a Callable is used for out, it is called on each row with the row as
only argument.

When `Nil` is used for out, the output is completely suppressed. This can
be useful when streaming, and the output is not required, but the
side-effects of e.g. an `on-in` hook is dealing with the data.

- Str:U

        my $str = csv(in => $in, out => Str);

    Returns a single String of CSV data.

- Str:D

        my $str = csv(in => $in, out => "out.csv");

    Writes the data as CSV to the named file.

- Array:U

        my $aoa = csv(in => $in, out => Array);

    Returns an Array of Arrays.

- Array:D

        my $aoa = csv(in => $in, out => @data);

    Adds the records to an existing Array. If the existing array is not empty,
    the type of the first record determines adding a list of Arrays or a list
    of Hashes.

- Hash:U

        my $aoh = csv(in => $in, out => Hash);

    Returns an Array of Hashes

- IO:D

        my $io = open "file.csv", :w;
        csv(in => $in, out => $io);

    Writes the data as CSV to the IO handle.

- Callable, Block, Sub, Routine

        my @d;
        csv(in => $in, out => { @d.push: $_ });

    Passes the data rows to the Callable

- Channel:U

        my $ch = csv(in => $in, out => Channel, :!meta);
        react {
            whenever $ch -> \row {
                @d.push: row;
                LAST { done; }
                }
            }

    Writes the data rows into a new Channel, which is returned.

- Channel:D

        my $ch = Channel.new;
        my $pr = start {
            react {
                whenever $ch -> \row {
                    @d.push: row;
                    LAST { done; }
                    }
                }
            }
        csv(in => $in, out => $ch);
        await $pr;

    Writes the data rows into the existing Channel.

- Supplier:D

        my $sup = Supplier.new;
        $sup.Supply.tap (-> \row { @d.push: row; });
        csv(in => $in, out => $sup, :!meta);

    Writes the data rows into the Supplier.

- Supply:U

        my $sup = csv(in => $in, out => Supply, :!meta);
        $ch.tap (-> \row { @d.push: row; });

    Writes the data rows into a new Supply.

### encoding


If passed, it should be an encoding accepted by the `:encoding()` option
to `open`. There is no default value.

If `encoding` is set to the literal value `"auto"`, the method ["header"](#header)
will be invoked on the opened stream to check if there is a BOM and set the
encoding accordingly. This is equal to passing True in the option
[`detect-bom`](#detect-bom).

### detect-bom



NYI for various reasons. Also see ["is-binary"](#is-binary)

If `detect-bom` is given, the method ["header"](#header) will be invoked on the
opened stream to check if there is a BOM and set the encoding accordingly.

`detect_bom` can be abbreviated to `bom`.

This is the same as setting [`encoding`](#encoding) to `"auto"`.

Note that as the method ["header"](#header) is invoked, its default is to also set
the headers.

### headers


If this attribute is not given, the default behavior is to produce an array
of arrays.

If `headers` is supplied, it should be an Array of column names, a Bool, a
Hash, a Callable, or a literal flag: `auto`, `lc`, `uc`, or `skip`.

- skip

    When `skip` is used, the header will not be included in the output.

        my $aoa = csv(in => $fh, headers => "skip");

- auto

    If `auto` is used, the first line of the `CSV` source will be read as the
    list of field headers and used to produce an array of hashes.

        my $aoh = csv(in => $fh, headers => "auto");

- lc

    If `lc` is used, the first line of the `CSV` source will be read as the
    list of field headers mapped to lower case and used to produce an array of
    hashes. This is a variation of `auto`.

        my $aoh = csv(in => $fh, headers => "lc");

- uc

    If `uc` is used, the first line of the `CSV` source will be read as the
    list of field headers mapped to upper case and used to produce an array of
    hashes. This is a variation of `auto`.

        my $aoh = csv(in => $fh, headers => "uc");

- Bool

    If `True` is passed, the method ["header"](#header) will be invoked with the
    default options on the opened stream to check if there is a BOM and set the
    encoding accordingly, detect and set [`sep`](#sep), [`eol`](#eol) and
    column names.

- Callable

    If a Callable is used, the first line of the `CSV` source will be read as
    the list of mangled field headers in which each field is passed as the only
    argument to the coderef. This list is used to produce an array of hashes.

        my $i = 0;
        my $aoh = csv(in => $fh, headers => { $^h.lc ~ $i++ });

    this example is a variation of using `lc` where all headers are forced to
    be unique by adding an index.

- ARRAY

    If  `headers` is an Array, the entries in the list will be used as field
    names. The first line is considered data instead of headers.

        my $aoh = csv(in => $fh, headers => [< Foo Bar >]);

- HASH

    If `headers` is a Hash, this implies `auto`, but header fields for that
    exist as key in the Hash will be replaced by the value for that key. Given
    a CSV file like

        post-kode,city,name,id number,fubble
        1234AA,Duckstad,Donald,13,"X313DF"

    using

        csv (headers => %{ "post-kode" => "pc", "id number" => "ID" }, ...

    will return an entry like

        { pc     => "1234AA",
          city   => "Duckstad",
          name   => "Donald",
          ID     => "13",
          fubble => "X313DF",
          }

See also [`munge-column-names`](#munge-column-names) and
[`set-column-names`](#set-column-names).

### munge-column-names



If `munge-column-names` is set, the method ["header"](#header) is invoked on the
opened stream with all matching arguments to detect and set the headers.

`munge-column-names` can be abbreviated to `munge`.

### key


If passed, will default [`headers`](#headers) to `"auto"` and return a
hashref instead of an array of hashes. Allowed values are simple strings
or arrays where the first element is the joiner and the rest are the fields
to join to combine the key

    my $ref = csv(in => "test.csv", key =>        "code");
    my $ref = csv(in => "test.csv", key => [ ":", "code", "color" ]);

with test.csv like

    code,product,price,color
    1,pc,850,gray
    2,keyboard,12,white
    3,mouse,5,black

the first example will return

    { 1   => {
          code    => 1,
          color   => 'gray',
          price   => 850,
          product => 'pc'
          },
      2   => {
          code    => 2,
          color   => 'white',
          price   => 12,
          product => 'keyboard'
          },
      3   => {
          code    => 3,
          color   => 'black',
          price   => 5,
          product => 'mouse'
          }
      }

the second example will return

    { "1:gray"    => {
          code    => 1,
          color   => 'gray',
          price   => 850,
          product => 'pc'
          },
      "2:white"   => {
          code    => 2,
          color   => 'white',
          price   => 12,
          product => 'keyboard'
          },
      "3:black"   => {
          code    => 3,
          color   => 'black',
          price   => 5,
          product => 'mouse'
          }
      }

If `out` points to an existing Hash, the data will be added to that instead
(existing records will be overwritten on reading duplicate keys). It returns
the value passed to `out`:

    my $ref = csv(in => "test.csv", out => %hash, key =>        "code");
    my $ref = csv(in => "test.csv", out => %hash, key => [ ":", "code", "color" ]);

### fragment


Only output the fragment as defined in the ["fragment"](#fragment) method. This option
is ignored when _generating_ `CSV`. See ["out"](#out).

Combining all of them could give something like

    use Text::CSV qw( csv );
    my @aoh = csv(
        in       => "test.txt",
        encoding => "utf-8",
        headers  => "auto",
        sep_char => "|",
        fragment => "row=3;6-9;15-*",
        );
    say @aoh[15]{Foo};

### sep-set




If `sep-set` is set, the method ["header"](#header) is invoked on the opened stream
to detect and set [`sep`](#sep) with the given set.

`sep-set` can be abbreviated to `seps`.

Note that as the method ["header"](#header) is invoked, its default is to also set
the headers.

### set\_column\_names


If  `set_column_names` is passed,  the method ["header"](#header) is invoked on the
opened stream with all