Data::Munge(3pm)
π Data::Munge π
okay bestie, welcome to Data::Munge β the Data::Munge(3pm) page, but make it cute. It's a Perl module full of little utility functions that the author got tired of rewriting, so he justβ¦ wrote them down. iconic behavior, honestly. π«Ά
β¨ NAME β¨
Data::Munge β various utility functions. that's it, that's the name, short and slay. π
πΈ SYNOPSIS πΈ
here's the vibe check, bestie β read it and weep (affectionately):
use Data::Munge;
my $re = list2re qw/f ba foo bar baz/;
# $re = qr/bar|baz|foo|ba|f/;
print byval { s/foo/bar/ } $text;
# print do { my $tmp = $text; $tmp =~ s/foo/bar/; $tmp };
foo(mapval { chomp } @lines);
# foo(map { my $tmp = $_; chomp $tmp; $tmp } @lines);
print replace('Apples are round, and apples are juicy.', qr/apples/i, 'oranges', 'g');
# "oranges are round, and oranges are juicy."
print replace('John Smith', qr/(\w+)\s+(\w+)/, '$2, $1');
# "Smith, John"
my $trimmed = trim " a b c ";
# "a b c"
my $x = 'bar';
if (elem $x, [qw(foo bar baz)]) { ... }
# executes: $x is an element of the arrayref
my $contents = slurp $fh; # or: slurp *STDIN
# reads all data from a filehandle into a scalar
my $t = is_callable(sub {}); # true
my $f = is_callable("hello"); # false
eval_string('print "hello world\\n"'); # says hello
eval_string('die'); # dies
eval_string('{'); # throws a syntax error
my $fac = rec {
my ($rec, $n) = @_;
$n < 2 ? 1 : $n * $rec->($n - 1)
};
print $fac->(5); # 120
if ("hello, world!" =~ /(\w+), (\w+)/) {
my @captured = submatches;
# @captured = ("hello", "world")
}
like, look at all of that. so much utility. so much slay. π
π¦ DESCRIPTION π¦
so this module defines a few generally useful utility functions. the author got tired of redefining them or working around them, so he wrote this module. honestly? valid. we've all been there. π
π§ Functions π§
β list2re LIST
turns a list of strings into a regex that matches any of the strings. especially useful in combination with "keys". example:
my $re = list2re keys %hash;
$str =~ s/($re)/$hash{$1}/g;
this function takes special care to get several edge cases right, and bestie, these edge cases are important:
- Empty list β an empty argument list results in a regex that doesn't match anything. nothing. nada. it's giving "no thoughts, head empty". π
- Empty string β an argument list consisting of a single empty string results in a regex that matches the empty string (and nothing else).
- Prefixes β the input strings are sorted by descending length to ensure longer matches are tried before shorter matches. otherwise
list2re('ab', 'abcd')would generateqr/ab|abcd/, which (on its own) can never matchabcd(becauseabis tried first, and it always succeeds whereabcdcould). the audacity of that regex, fr fr. π
β byval BLOCK SCALAR
takes a code block and a value, runs the block with $_ set to that value, and returns the final value of $_. the global value of $_ is not affected. also $_ isn't aliased to the input value either, so modifying $_ in the block will not affect the passed in value. immaculate isolation, we love to see it. π
example:
foo(byval { s/!/?/g } $str);
# Calls foo() with the value of $str, but all '!' have been replaced by '?'.
# $str itself is not modified.
since perl 5.14 you can also use the "/r" flag:
foo($str =~ s/!/?/gr);
but "byval" works on all versions of perl and is not limited to "s///". versatile queen. π
β mapval BLOCK LIST
works like a combination of "map" and "byval"; i.e. it behaves like "map", but $_ is a copy, not aliased to the current element, and the return value is taken from $_ again (it ignores the value returned by the block). example:
my @foo = mapval { chomp } @bar;
# @foo contains a copy of @bar where all elements have been chomp'd.
# This could also be written as chomp(my @foo = @bar); but that's not
# always possible.
β submatches
returns a list of the strings captured by the last successful pattern match. normally you don't need this function because this is exactly what "m//" returns in list context. however, "submatches" also works in other contexts such as the RHS of "s//.../e". it's giving flexibility, it's giving range. π
β replace STRING, REGEX, REPLACEMENT, FLAG
β replace STRING, REGEX, REPLACEMENT
a clone of javascript's "String.prototype.replace". it works almost the same as byval { s/REGEX/REPLACEMENT/FLAG } STRING, but with a few important differences. REGEX can be a string or a compiled "qr//" object. REPLACEMENT can be a string or a subroutine reference. if it's a string, it can contain the following replacement patterns:
$$β Inserts a'$'.$&β Inserts the matched substring."$`"β Inserts the substring preceding the match."$'"β Inserts the substring following the match.$N(where N is a digit) β Inserts the substring matched by the *N*th capturing group."${N}"(where N is one or more digits) β Inserts the substring matched by the *N*th capturing group.
ngl, note that these aren't variables; they're character sequences interpreted by "replace". don't come for me, that's just how it is bestie. π
if REPLACEMENT is a subroutine reference, it's called with the following arguments: first the matched substring (like $& above), then the contents of the capture buffers (as returned by "submatches"), then the offset where the pattern matched (like "$-[0]", see "@-" in perlvar), then the STRING. the return value will be inserted in place of the matched substring. main character subroutine energy, honestly. β¨
normally only the first occurrence of REGEX is replaced. if FLAG is present, it must be 'g' and causes all occurrences to be replaced. periodt.
β trim STRING
returns STRING with all leading and trailing whitespace removed. like "length" it returns "undef" if the input is "undef". consistent. clean. self-care. π
β elem SCALAR, ARRAYREF
returns a boolean value telling you whether SCALAR is an element of ARRAYREF or not. two scalars are considered equal if they're both "undef", if they're both references to the same thing, or if they're both not references and "eq" to each other.
this is implemented as a linear search through ARRAYREF that terminates early if a match is found (i.e. elem 'A', ['A', 1 .. 9999] won't even look at elements 1 .. 9999). she doesn't waste time, she's efficient, we stan. π
β is_callable SCALAR
returns a boolean value telling you whether SCALAR can be called as a function. this is the case if SCALAR is either a reference to a subroutine (such as "\&foo" or sub { ... }) or an object with an overloaded '&{}' operator (see "* Dereferencing" in overload).
β eval_string STRING
evals STRING just like "eval" but doesn't catch exceptions. caveat: unlike with "eval" the code runs in an empty lexical scope:
my $foo = "Hello, world!\n";
eval_string 'print $foo';
# Dies: Global symbol "$foo" requires explicit package name
that is, the eval'd code can't see variables from the scope of the "eval_string" call. boundaries, bestie. it has them. π§
β slurp FILEHANDLE
reads and returns all remaining data from FILEHANDLE as a string, or "undef" if it hits end-of-file. (interaction with non-blocking filehandles is currently not well defined.) π
"slurp $handle" is equivalent to "do { local $/; scalar readline $handle }". short queen, does exactly what it says.
β rec BLOCK
creates an anonymous sub as sub BLOCK would, but supplies the called sub with an extra argument that can be used to recurse:
my $code = rec {
my ($rec, $n) = @_;
$rec->($n - 1) if $n > 0;
print $n, "\n";
};
$code->(4);
that is, when the sub is called, an implicit first argument is passed in $_[0] (all normal arguments are moved one up). this first argument is a reference to the sub itself. this reference could be used to recurse directly or to register the sub as a handler in an event system, for example. it's giving self-aware. it's giving main character energy. π
a note on defining recursive anonymous functions: doing this right is more complicated than it may at first appear. the most straightforward solution using a lexical variable and a closure leaks memory because it creates a reference cycle. starting with perl 5.16 there is a "__SUB__" constant that is equivalent to $rec above, and this is indeed what this module uses (if available). no cap.
however, this module works even on older perls by falling back to either weak references (if available) or a "fake recursion" scheme that dynamically instantiates a new sub for each call instead of creating a cycle. this last resort is slower than weak references but works everywhere. she's got backup plans for her backup plans. π
π AUTHOR π
Lukas Mai, "<l.mai at web.de>" β the icon behind all of this. π«Ά
π COPYRIGHT & LICENSE π
Copyright 2009-2011, 2013-2015, 2023-2024 Lukas Mai.
this program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.
see https://dev.perl.org/licenses/ for more information.
okay that's the whole page, bestie, you made it to the end, so proud of you. π₯Ή this was Data::Munge(3pm) from perl v5.38.2, dated 2024-07-29 β go forth and munge your data, you absolute legend. β¨πππ¦πΈπ
π¦ where this page comes from
- debian trixie: libdata-munge-perl 0.111-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libdata-munge-perl 0.111-1 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libdata-munge-perl 0.111-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