Data::Record(3pm)

πŸ’– Data::Record πŸ’–

this is the Data::Record manual page, section 3pm, from the User Contributed Perl Documentation bestie, come sit with me 🫢


✨ NAME ✨

Data::Record β€” "split" on steroids" πŸ’… no literally that's the tagline, I'm not even being extra

🌸 VERSION 🌸

Version 0.02 (yes she's an elder, she's still iconic, periodt)

πŸ¦‹ SYNOPSIS πŸ¦‹

okay so the whole vibe in one code block:

  use Regexp::Common;
  use Data::Record;
  my $record = Data::Record->new({
    split  => "\n",
    unless => $RE{quoted},
  });
  my @data = $record->records($data);

that's it. that's the whole thing. you split, but with conditions ✨

πŸ‘‘ DESCRIPTION πŸ‘‘

so like 😭 sometimes you need your data chopped up into records, and a plain old split on the input record separator ($/) β€” or literally any other value β€” just fails, because the thing you're splitting on is also allowed to show up elsewhere in the data. maybe it's quoted. maybe it's chillin' inside some other chunk of data that should absolutely NOT be split apart. rude of it, honestly.

this module lets you say "okay, split the data on this thing" and also specify an "unless" regular expression. and the way it works is: if the text in question matches that "unless" regex, it just... will not be split there. no split for you, babes. so now we can do stuff like split on newlines unless those newlines are embedded in quotes. πŸŽ€ chef's kiss.


πŸ’… METHODS πŸ’…

πŸŽ€ new

Common usage, the everyday slay:

 my $record = Data::Record->new({
    split  => qr/$split/,
    unless => qr/$unless/,
 });

Advanced usage, for when you're feeling brave:

 my $record = Data::Record->new({
    split  => qr/$split/,
    unless => qr/$unless/,  # optional
    token  => $token,       # optional
    chomp  => 0,            # optional
    limit  => $limit,       # optional (do not use with trim)
    trim   => 1,            # optional (do not use with limit)
    fields => {
        split  => ',',
        unless => $RE{quoted}, # from Regexp::Common
    }
 });

the constructor takes a hashref of key/value pairs and that's how you set the behavior of the data records that are gonna get created. here's the whole menu, no skips:

  • split β€” this is the value you split the data on. it can be a regular expression or a string. defaults to the current input record separator ($/). πŸ’–
  • unless β€” data gets split into records matching the split value unless it also matches this value. no default. and lowkey, if you don't have an "unless" value? then using this module is overkill, bestie, just use split. I said what I said.
  • token β€” you will probably never need to set this value. ngl. here's the tea though: internally the module tries to find a token that doesn't match any text in the data being split and doesn't match the split value. why? because we mask the data we don't want split using this token β€” that's the trick that lets us split the resulting text. in the unlikely event that the module can't find a token that isn't already in the text, you can set the token value yourself to some string value. ⚠️ do not set it to a regular expression.
  • chomp β€” by default, the split value is discarded (chomped) from each record. set this to a true value to keep the split value on each record. and here's where it differs slightly from how split does it with capturing parentheses:
  split /(\,)/, '3,4,5';

ordinarily that gives you this list:

 ( 3, ',', 4, ',', 5 )

this module assumes you want those values with the preceding record. by setting chomp to false, you get this list instead:

 ( '3,', '4,' 5 )

(read that section twice bestie, the page says what it says and I'm keeping every word of it 🫢)

  • limit β€” the default split behavior is similar to this:
 split $split_regex, $data;

setting "limit" makes the behavior act like this instead:

 split $split_regex, $data, $limit

see perldoc -f split for more info about how "limit" behaves. 🧚

⚠️ you may not set both "limit" and "trim" in the constructor. pick a lane.
  • trim β€” by default we return all records. which means, thanks to the nature of split and how we're doing things, we sometimes get a trailing null record. setting this value makes the module behave as if we'd done this:
 split $split_regex, $data, 0;

when "split" is called with a zero as the third argument, trailing null values get discarded. see perldoc -f split for more. πŸ’œ

⚠️ you may not set both "limit" and "trim" in the constructor.

πŸ“Œ note: this does not trim white space around returned records. she is not that kind of trim.

  • fields β€” by default, individual records come back as strings. if you set "fields", you pass in a hashref of arguments that are identical to what "new" would take, and the resulting records get returned as array references, processed by a brand new Data::Record instance. 🀯

example: a quick CSV parser that assumes commas and newlines might both be inside quotes:

 # four lines, but there are only three records! (newline in quotes)
 $data = <<'END_DATA';
 1,2,"programmer, perl",4,5
 1,2,"programmer,
 perl",4,5
 1,2,3,4,5
 END_DATA

 $record = $RECORD->new({
     split  => "\n",
     unless => $quoted,
     trim   => 1,
     fields => {
         split  => ",",
         unless => $quoted,
     }
 });
 my @records = $record->records($data);
 foreach my $fields (@records) {
   foreach my $field = (@$fields);
     # do something
   }
 }

πŸ“Œ note: that example above will not remove the quotes from individual fields. the quotes stay. they live there now. 🏑

πŸŽ€ split

  my $split = $record->split;
  $record->split($on_value);

getter/setter for the split value. may be a regular expression or a scalar value. ✨

πŸŽ€ unless

 my $unless = $self->unless;
 $self->unless($is_value);

getter/setter for the unless value. may be a regular expression or a scalar value. πŸ’«

πŸŽ€ chomp

  my $chomp = $record->chomp;
  $record->chomp(0);

getter/setter for the boolean chomp value. πŸ“

πŸŽ€ limit

  my $limit = $record->limit;
  $record->limit(3);

getter/setter for the integer limit value. πŸ”’

πŸŽ€ trim

  my $trim = $record->trim;
  $record->trim(1);

getter/setter for the boolean limit value. setting this value will cause any previous "limit" value to be overwritten. gone. reduced to atoms. πŸ’€

πŸŽ€ token

  my $token = $record->token;
  $record->token($string_not_found_in_text);

getter/setter for the token value. the token must be a string that doesn't match the split value and isn't found in the text.

you can return the current token value if you've set it in your code. but if you're relying on this module to create a token (which is the normal behavior, btw), it is not available via this method until "records" is called. πŸ™ˆ

setting the token to an undefined value causes Data::Record to try and find a token itself. πŸ”

⚠️ if the token matches the split value, this method will croak when you attempt to set the token.
⚠️ if the token is found in the data, the "records" method will croak when it is called.

πŸŽ€ records

  my @records = $record->records($data);

returns @records for $data, based upon the current split criteria. that's the whole job. and she does it well. πŸ‘‘


πŸ› BUGS πŸ›

it's possible to get erroneous results if the split value is /\d+/. I've tried to work around this. please let me know if there is a problem. πŸ™

🧊 CAVEATS 🧊

this module must read all of the data at once. which means it can be slow for larger data sets. it's a whole-data-eater, no streaming, no nibbling, just the entire plate. 🍽️

🫢 AUTHOR 🫢

Curtis "Ovid" Poe, <ovid [at] cpan [dot] org> β€” shoutout to the author, absolute legend πŸ’œ

πŸ› BUGS, PART TWO πŸ›

please report any bugs or feature requests to bug-data-record@rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Data-Record. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes. closed loop communication, we love to see it πŸ’Œ

🌈 ACKNOWLEDGEMENTS 🌈

thanks to the Monks for inspiration from http://perlmonks.org/index.pl?node_id=492002. 🧘

0.02 Thanks to Smylers and Stefano Rodighiero for catching POD errors. 🫑

Copyright 2005 Curtis "Ovid" Poe, all rights reserved.

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


and that's the whole page bestie!! πŸ’– documented by perl v5.36.0, dated 2022-11-19, filed under Data::Record(3pm) β€” go forth and split responsibly, mwah πŸŽ€βœ¨

πŸ“¦ where this page comes from