Catmandu::Util(3pm)

πŸ“¦
version 1.2025 Β· 4 versions
, in ubuntu resolute, ubuntu stonking

okay bestie, sit down, we're doing Catmandu::Util(3pm) today πŸ’– this one lives in the User Contributed Perl Documentation corner of the man world, and it is literally just a giant goodie bag of helper functions. It's giving Swiss Army knife but make it Perl. It's giving "I have a function for that". Let's go. ✨


πŸ“› NAME πŸ“›

Catmandu::Util β€” a whole collection of utility functions. That's it, that's the name, no cap. πŸŽ€


🌸 SYNOPSIS 🌸

use Catmandu::Util qw(:string);

$str = trim($str);

like... you import a tag group, you call a function, you move on with your life. iconic. πŸ’…


πŸ’« FUNCTIONS πŸ’«

πŸ¦‹ IO functions πŸ¦‹

use Catmandu::Util qw(:io);

io($io, %opts)

Bestie, this one takes a file path, a glob, a glob reference, a scalar reference or an IO::Handle object and hands you back an opened IO::Handle object. It's the "gimme whatever, I'll deal" function. 🫢

my $fh = io '/path/to/file';

my $fh = io *STDIN;

my $fh = io \*STDOUT, mode => 'w', binmode => ':crlf';

my $write_cb = sub { my $str = $_[0]; ... };

my $fh = io $write_cb, mode => 'w';

my $scalar = "";
my $fh = io \$scalar, mode => 'w';
$fh->print("some text");

Options are:

  • mode β€” default is "r". πŸ“–
  • binmode β€” default is ":encoding(UTF-8)". ✨
  • encoding β€” alias for binmode. Same thing, different name, we love a rebrand. πŸ’…

read_file($path);

deprecated bestie 😭 it's giving legacy. use tools like Path::Tiny instead.

Reads the file at $path into a string.

my $str = read_file('/path/to/file.txt');

Throws a Catmandu::Error on failure. πŸ’€

read_io($io)

Reads an IO::Handle into a string.

my $str = read_file($fh);

(yep, exactly like that in the page πŸ‘€)

write_file($path, $str);

deprecated 😭 and the page literally says "use tools like use tools like File::Slurp::Tiny instead" πŸ’€ so β€” use File::Slurp::Tiny instead.

Writes the string $str to a file at $path.

write_file('/path/to/file.txt', "contents");

Throws a Catmandu::Error on failure.

read_yaml($path);

Reads the YAML file at $path into a Perl hash.

my $cfg = read_yaml($path);

Dies on failure reading the file or parsing the YAML. 😡

read_json($path);

Same energy, JSON flavored 🌈

my $cfg = read_json($path);

Dies on failure reading the file or parsing the JSON. πŸ’€

join_path(@path);

Joins relative paths into an absolute path.

join_path('/path/..', './to', 'file.txt');
# => "/to/file.txt"

normalize_path($path);

Normalizes a relative path to an absolute path.

normalize_path('/path/../to/./file.txt');
# => "/to/file.txt"

segmented_path($path);

my $id = "FB41144C-F0ED-11E1-A9DE-61C894A0A6B4";
segmented_path($id, segment_size => 4);
# => "FB41/144C/F0ED/11E1/A9DE/61C8/94A0/A6B4"
segmented_path($id, segment_size => 2, base_path => "/files");
# => "/files/FB/41/14/4C/F0/ED/11/E1/A9/DE/61/C8/94/A0/A6/B4"

content_type($filename);

Guess the content type of a file name. πŸ”

content_type("book.pdf");
# => "application/pdf"

πŸ—‚οΈ Hash functions πŸ—‚οΈ

use Catmandu::Util qw(:hash);

A collection of functions that operate on hash references.

hash_merge($hash1, $hash2, ... , $hashN)

Merge $hash1 through $hashN, with the nth-most (rightmost) hash taking precedence. Returns a new hash reference representing the merge. Rightmost wins β€” main character energy, honestly. πŸ‘‘

hash_merge({a => 1}, {b => 2}, {a => 3});
# => { a => 3 , b => 2}

🧺 Array functions 🧺

use Catmandu::Util qw(:array);

A collection of functions that operate on array references.

array_exists($array, $index)

Returns 1 if $index is in the bounds of $array. Bounds check but make it cute. ✨

array_exists(["a", "b"], 2);
# => 0
array_exists(["a", "b"], 1);
# => 1

array_group_by($array, $key)

my $list = [{color => 'black', id => 1},
            {color => 'white', id => 2},
            {id => 3},
            {color => 'black', id => 4}];
array_group_by($list, 'color');
# => {black => [{color => 'black', id => 1}, {color => 'black', id => 4}],
#     white => [{color => 'white', id => 2}]}

array_pluck($array, $key)

my $list = [{id => 1}, {}, {id => 3}];
array_pluck($list, 'id');
# => [1, undef, 3]

array_to_sentence($array), array_to_sentence($array, $join), array_to_sentence($array, $join, $join_last)

three signatures, one function, all the grammar vibes πŸ’–

array_to_sentence([1,2,3]);
# => "1, 2 and 3"
array_to_sentence([1,2,3], ",");
# => "1,2 and 3"
array_to_sentence([1,2,3], ",", " & ");
# => "1,2 & 3"

array_sum($array)

array_sum([1,2,3]);
# => 6

array_includes($array, $val)

Returns 1 if $array includes a value that is deeply equal to $val, 0 otherwise. Comparison is done with is_same(). Deep equality, we love to see it. 🫢

array_includes([{color => 'black'}], {color => 'white'});
# => 0
array_includes([{color => 'black'}], {color => 'black'});
# => 1

array_any($array, \&sub)

array_any(["green", "blue"], sub { my $color = $_[0]; $color eq "blue" });
# => 1

array_rest($array)

Returns a copy of $array without the head. (head = gone, not invited. πŸ™ˆ)

array_rest([1,2,3,4]);
# => [2,3,4]
array_rest([1]);
# => []

array_uniq($array)

Returns a copy of $array with all duplicates removed. duplicates? never heard of her. πŸ’…

array_split($array | $string)

Returns $array or a new array by splitting $string at commas.


🧡 String functions 🧡

use Catmandu::Util qw(:string);

as_utf8($str)

Returns a copy of $str flagged as UTF-8. ✨

trim($str)

Returns a copy of $str with leading and trailing whitespace removed.

capitalize($str)

Equivalent to "ucfirst lc as_utf8 $str". lowercase era over, capitalized era begins. πŸ‘‘


πŸ•΅οΈ Is functions πŸ•΅οΈ

use Catmandu::Util qw(:is);

is_number(42) ? "it's numeric" : "it's not numeric";

is_maybe_hash_ref({});
# => 1
is_maybe_hash_ref(undef);
# => 1
is_maybe_hash_ref([]);
# => 0

A collection of predicate functions that test the type or value of argument $val. Each function (except is_same() and "is_different") also has a maybe variant that also tests true if $val is undefined. Returns 1 or 0. yes/no, true/false, the whole vibe check.

is_invocant($val) / is_maybe_invocant($val)

Tests if $val is callable (is an existing package or blessed object).

is_able($val, @method_names) / is_maybe_able($val, @method_names)

Tests if $val is callable and has all methods in @method_names.

is_instance($val, @class_names) / is_maybe_instance($val, @class_names)

Tests if $val is a blessed object and an instance of all the classes in @class_names.

is_ref($val) / is_maybe_ref($val)

Tests if $val is a reference. Equivalent to "ref $val ? 1 : 0".

is_scalar_ref($val) / is_maybe_scalar_ref($val)

Tests if $val is a scalar reference.

is_array_ref($val) / is_maybe_array_ref($val)

Tests if $val is an array reference.

is_hash_ref($val) / is_maybe_hash_ref($val)

Tests if $val is a hash reference.

is_code_ref($val) / is_maybe_code_ref($val)

Tests if $val is a subroutine reference.

is_regex_ref($val) / is_maybe_regex_ref($val)

Tests if $val is a regular expression reference generated by the "qr//" operator.

is_glob_ref($val) / is_maybe_glob_ref($val)

Tests if $val is a glob reference.

is_value($val) / is_maybe_value($val)

Tests if $val is a real value (defined, not a reference and not a glob.

is_string($val) / is_maybe_string($val)

Tests if $val is a non-empty string. Equivalent to "is_value($val) && length($val) > 0".

is_number($val) / is_maybe_number($val)

Tests if $val is a number.

is_integer($val) / is_maybe_integer($val)

Tests if $val is an integer.

is_natural($val) / is_maybe_natural($val)

Tests if $val is a non-negative integer. Equivalent to "is_integer($val) && $val >= 0".

is_positive($val) / is_maybe_positive($val)

Tests if $val is a positive integer. Equivalent to "is_integer($val) && $val >= 1".

is_float($val) / is_maybe_float($val)

Tests if $val is a floating point number.

is_same($val, $other_val)

Tests if $val is deeply equal to $other_val.

is_different($val, $other_val)

The opposite of is_same(). πŸ’€


βœ… Check functions βœ…

use Catmandu::Util qw(:check);

check_hash_ref({color => 'red'});
# => {color => 'red'}
check_hash_ref([]);
# dies

A group of assert functions similar to the ":is" group, but instead of returning true or false they return their argument or die. πŸ’€ very "do it or else" of them.

Here's the whole roster, bestie:

check_invocant($val)
check_maybe_invocant($val)
check_able($val, @method_names)
check_maybe_able($val, @method_names)
check_instance($val, @class_names)
check_maybe_instance($val, @class_names)
check_ref($val)
check_maybe_ref($val)
check_scalar_ref($val)
check_maybe_scalar_ref($val)
check_array_ref($val)
check_maybe_array_ref($val)
check_hash_ref($val)
check_maybe_hash_ref($val)
check_code_ref($val)
check_maybe_code_ref($val)
check_regex_ref($val)
check_maybe_regex_ref($val)
check_glob_ref($val)
check_maybe_glob_ref($val)
check_value($val)
check_maybe_value($val)
check_string($val)
check_maybe_string($val)
check_number($val)
check_maybe_number($val)
check_integer($val)
check_maybe_integer($val)
check_natural($val)
check_maybe_natural($val)
check_positive($val)
check_maybe_positive($val)
check_float($val)
check_maybe_float($val)
check_same($val, $other_val)
check_different($val, $other_val)

πŸ₯° Human output functions πŸ₯°

use Catmandu::Util qw(:human);

human_number($num)

Insert a comma at 3-digit intervals to make $num more readable. Only works with integers for now.

human_number(64354);
# => "64,354"

human_byte_size($size)

human_byte_size(64);
# => "64 bytes"
human_byte_size(10005000);
# => "10.01 MB"

human_content_type($content_type), human_content_type($content_type, $default)

human_content_type('application/x-dos_ms_excel');
# => "Excel"
human_content_type('application/zip');
# => "ZIP archive"
human_content_type('foo/x-unknown');
# => "foo/x-unknown"
human_content_type('foo/x-unknown', 'Unknown');
# => "Unknown"

πŸ“œ XML functions πŸ“œ

use Catmandu::Util qw(:xml);

xml_declaration()

Returns qq(<?xml version="1.0" encoding="UTF-8"?>\n).

xml_escape($str)

Returns an XML escaped copy of $str.


🧚 Miscellaneous functions 🧚

require_package($pkg), require_package($pkg, $namespace)

Load package $pkg at runtime with "require" and return its full name.

my $pkg = require_package('File::Spec');
my $dir = $pkg->tmpdir();

πŸ“ okay bestie, that's the first chunk of this page β€” and there's more still coming, so don't go anywhere πŸ’–

require_package('Util', 'Catmandu');
# => "Catmandu::Util"
require_package('Catmandu::Util', 'Catmandu');
# => "Catmandu::Util"

And bestie, if it can't find what you asked for? It throws a Catmandu::Error. Not a warning, not a lil shrug β€” a whole error. So wrap it or handle it, okay? πŸ’…


use_lib(@dirs) πŸ’–

Adds directories to @INC at runtime. Like, right then and there, mid-script. You're not editing your environment, you're just sliding these dirs into Perl's search path while it's already running. Very main character of you. ✨

And yeah β€” if it can't do it, it throws a Catmandu::Error. No cap.

pod_section($package_or_file, $section [, @options] ) πŸ“–

Okay so this one pulls up documentation for a package β€” but only for the section you pick. So you say which package (or file) and which section, and it hands you just that chunk.

Any extra @options you pass along get forwarded straight to Pod::Usage. So whatever Pod::Usage likes, this likes. πŸŽ€


now($format) πŸ•βœ¨

Returns the current datetime as a string. Iconic, simple, obsessed.

So $format can be any strftime format you want β€” go wild, it's your clock. But there are also 2 builtin formats you can just say by name:

  • iso_date_time β€” literally equivalent to %Y-%m-%dT%H:%M:%SZ
  • iso_date_time_millis β€” same exact thing, but with milliseconds added on top. Fancy. πŸ”₯
now('%Y/%m/%d');
now('iso_date_time_millis');

And if you don't pass a $format at all? The default is iso_date_time. So it's got you covered even when you're being lazy. 🫢


And that's a wrap, bestie! πŸŽ€ This whole page is from Catmandu::Util(3pm), documented for perl v5.40.1, dated 2026-01-24. Slay, go forth, and may your @INC always be correct. πŸ’–βœ¨

πŸ“¦ where this page comes from