Data::...:Field(3pm)
π Data::TableReader::Field π
okay bestie, so this is Data::TableReader::Field β a lil' class from the User Contributed Perl Documentation that describes aspects of one of the fields you wanna find in your spreadsheet. like, one column's whole personality. that's it. that's the class. π
β¨ VERSION β¨
version 0.021 β she's giving current, she's giving maintained π«Ά
πΈ DESCRIPTION πΈ
so basically, this class describes aspects of one of the fields you want to find in your spreadsheet. one field = one object. no cap.
π ATTRIBUTES π
name
Required. it's used for the hashref key if you pull records as hashes, and it also shows up in diagnostic messages. so like, name your fields something you can live with, bestie π
addr
convenience for refaddr($field). use this any time you use the field as a key in a hashref, if there's any chance your names aren't distinct. like, if two fields could be twinning, use the addr. periodt.
header
a string or regex describing the column header you want to find in the spreadsheet. β¨
- if you specify a regex, it's used directly.
- if you specify a string, it becomes the regex matching any string with the same words (
\w+) and non-whitespace (\S+) characters in the same order, case insensitive, surrounded by any amount of non-alphanumeric garbage ("[\W_]*").
when no header is specified, the name is used as a string after first breaking it into words on underscore or camel-case or numeric boundaries. π¦
this deserves some examples, and honestly? the examples ate:
Name Implied Default Header
"zipcode" "zipcode"
"ZipCode" "Zip Code"
"Zip_Code" "zip Code"
"zip5" "zip 5"
Header Regex Could Match...
"ZipCode" /^[\W_]*ZipCode[\W_]*$/i "zipcode:"
"zip_code" /^[\W_]*zip_code[\W_]*$/i "--ZIP_CODE--"
"zip code" /^[\W_]*zip[\W_]*code[\W_]*$/i "ZIP\nCODE "
"zip-code" /^[\W_]*zip[\W_]*-[\W_]*code[\W_]*$/i "ZIP-CODE:"
qr/Zip.*Code/ /Zip.*Code/ "Post(Zip)Code"
if this default matching doesn't meet your needs or your paranoia level π, then you should always specify your own header regexes. fr fr.
(if your data actually doesn't have any header at all and you want to brazenly assume the columns match the fields, see reader attribute header_row_at in Data::TableReader) π
required
whether or not this field must be found in order to detect a table. default is true. note this does not require the field of a row to contain data in order to read a record from the table β it just requires a column to exist. big difference, iykyk.
trim
# remove leading/trailing whitespace
trim => 1
# remove leading/trailing whitespace but also remove "N/A" and "NULL"
trim => qr( ^ \s* N/A \s* $ | ^ \s* NULL \s* $ | ^ \s+ | \s+ $ )xi
# custom search/replace in a coderef
trim => sub { s/[\0-\1F\7F]+/ /g; s/^\s+//; s/\s+$//; };
so here's the tea π:
- if set to a non-reference, it's treated as a boolean of whether to remove leading and trailing whitespace.
- if set to a coderef, the coderef gets called for each value with
$_set to the current value; it should modify$_as appropriate (return value is ignored). - it can also be set to a regular expression of all the patterns to remove, as per
s/$regexp//g.
default is 1, which is equivalent to a regular expression of qr/(^\s+)|(\s+$)/. slay. β¨
blank
the value to extract when the spreadsheet cell is an empty string or undef. (after any processing done by trim) default is undef. another common value would be "". π
type
a Type::Tiny type (or any object or class with a validate method) or a coderef which returns a validation error message (undef if it is valid). π
use Types::Standard;
...
type => Maybe[Int]
# or without Type::Tiny
type => sub { $_[0] =~ /^\w+/? undef : "word-characters only" },
this is an optional feature and there is no default. the behavior of a validation failure depends on the options to TableReader. so like, don't come for me, go read that one π
coerce
if type validation fails, this gives you a second chance at fixing the field. π«Ά
- set this to a true value to call
$field->type->coerceon the value, or - set it to a coderef of the form
$coerced_value= $coerce->($value).
type validation will be attempted a second time on the coerced value, and if successful it replaces the original value. if it fails, the original value remains in the record (and you can handle it how you like in the TableReader on_validation_error callback).
if you want to apply a coercion before the first type validation is attempted, you can put that logic into the trim attribute. π§
array
boolean of whether this field can be found multiple times in one table. default is false. if true, the value of the field will always be an arrayref (even if only one column matched). π no cap, always.
follows
name (or arrayref of names) of a field which this field must follow, in a first-to-last ordering of the columns. this field must occur immediately after the named field(s), or after another field which also has a follows restriction and follows the named field(s). β¨
the purpose of this attribute is to resolve ambiguous columns. suppose you expect columns with the following headers:
Father | | | | Mother | | |
FirstName | LastName | Tel. | Email | FirstName | LastName | Tel. | Email
you can use qr/Father\nFirstName/ to identify the first column, but after FirstName the rest are ambiguous. but, TableReader can figure it out if you say:
{ name => 'father_first', header => qr/Father\nFirstName/ },
{ name => 'father_last', header => 'LastName', follows => 'father_first' },
{ name => 'father_tel', header => 'Tel.', follows => 'father_first' },
{ name => 'father_email', header => 'Email', follows => 'father_first' },
..
and so on. note how 'father_first' is used for each as the follows name; this way if any non-required fields (like maybe Tel) are completely removed from the file, TableReader will still be able to find LastName and Email. π₯
you can also use this to accumulate an array of columns that lack headers:
Scores | | | | | | | OtherData
12% | 35% | 42% | 18% | 65% | 99% | 55% | xyz
{ name => 'scores', array => 1, trim => 1 },
{ name => 'scores', array => 1, trim => 1, header => '', follows => 'scores' },
the second field definition has an empty header, which would normally make it rather ambiguous and potentially capture blank-header columns that might not be part of the array. but, because it must follow a column named 'scores' there's no ambiguity; you get exactly any column starting from the header 'Scores' until a column of any other header. obsessed. π
follows_list
convenience accessor for @{ ->follows }, useful because follows might be either a scalar or arrayref. π
header_regex
header, coerced to a regex if it wasn't already. π
π AUTHOR π
Michael Conrad <mike@nrdvana.net>
π COPYRIGHT AND LICENSE π
this software is copyright (c) 2024 by Michael Conrad.
this is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. π«Ά
and that's the whole page bestie!! πΈ she's version 0.021, she's perl v5.38.2, dated 2024-06-21, and she's giving User Contributed Perl Documentation energy. go forth and parse those spreadsheets. slay. πβ¨
π¦ where this page comes from
- debian trixie: libdata-tablereader-perl 0.021-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libdata-tablereader-perl 0.021-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libdata-tablereader-perl 0.021-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms