.\" Automatically generated by Pod::Man 4.11 (Pod::Simple 3.35)
.\"
.\" Standard preamble:
.\" ========================================================================
.de Sp \" Vertical space (when we can't use .PP)
.if t .sp .5v
.if n .sp
..
.de Vb \" Begin verbatim text
.ft CW
.nf
.ne \\$1
..
.de Ve \" End verbatim text
.ft R
.fi
..
.\" Set up some character translations and predefined strings. \*(-- will
.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
.\" double quote, and \*(R" will give a right double quote. \*(C+ will
.\" give a nicer C++. Capital omega is used to do unbreakable dashes and
.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
.\" nothing in troff, for use with C<>.
.tr \(*W-
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.ie n \{\
. ds -- \(*W-
. ds PI pi
. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
. ds L" ""
. ds R" ""
. ds C` ""
. ds C' ""
'br\}
.el\{\
. ds -- \|\(em\|
. ds PI \(*p
. ds L" ``
. ds R" ''
. ds C`
. ds C'
'br\}
.\"
.\" Escape single quotes in literal strings from groff's Unicode transform.
.ie \n(.g .ds Aq \(aq
.el .ds Aq '
.\"
.\" If the F register is >0, we'll generate index entries on stderr for
.\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
.\" entries marked with X<> in POD. Of course, you'll have to process the
.\" output yourself in some meaningful fashion.
.\"
.\" Avoid warning from groff about undefined register 'F'.
.de IX
..
.nr rF 0
.if \n(.g .if rF .nr rF 1
.if (\n(rF:(\n(.g==0)) \{\
. if \nF \{\
. de IX
. tm Index:\\$1\t\\n%\t"\\$2"
..
. if !\nF==2 \{\
. nr % 0
. nr F 2
. \}
. \}
.\}
.rr rF
.\" ========================================================================
.\"
.IX Title "Mojo::Util 3"
.TH Mojo::Util 3 "2023-04-27" "perl v5.26.3" "User Contributed Perl Documentation"
.\" For nroff, turn off justification. Always turn off hyphenation; it makes
.\" way too many mistakes in technical documents.
.if n .ad l
.nh
.SH "NAME"
Mojo::Util \- Portable utility functions
.SH "SYNOPSIS"
.IX Header "SYNOPSIS"
.Vb 1
\& use Mojo::Util qw(b64_encode url_escape url_unescape);
\&
\& my $str = \*(Aqtest=23\*(Aq;
\& my $escaped = url_escape $str;
\& say url_unescape $escaped;
\& say b64_encode $escaped, \*(Aq\*(Aq;
.Ve
.SH "DESCRIPTION"
.IX Header "DESCRIPTION"
Mojo::Util provides portable utility functions for Mojo.
.SH "FUNCTIONS"
.IX Header "FUNCTIONS"
Mojo::Util implements the following functions, which can be imported individually.
.SS "b64_decode"
.IX Subsection "b64_decode"
.Vb 1
\& my $bytes = b64_decode $b64;
.Ve
.PP
Base64 decode bytes with MIME::Base64.
.SS "b64_encode"
.IX Subsection "b64_encode"
.Vb 2
\& my $b64 = b64_encode $bytes;
\& my $b64 = b64_encode $bytes, "\en";
.Ve
.PP
Base64 encode bytes with MIME::Base64, the line ending defaults to a newline.
.SS "camelize"
.IX Subsection "camelize"
.Vb 1
\& my $camelcase = camelize $snakecase;
.Ve
.PP
Convert \f(CW\*(C`snake_case\*(C'\fR string to \f(CW\*(C`CamelCase\*(C'\fR and replace \f(CW\*(C`\-\*(C'\fR with \f(CW\*(C`::\*(C'\fR.
.PP
.Vb 2
\& # "FooBar"
\& camelize \*(Aqfoo_bar\*(Aq;
\&
\& # "FooBar::Baz"
\& camelize \*(Aqfoo_bar\-baz\*(Aq;
\&
\& # "FooBar::Baz"
\& camelize \*(AqFooBar::Baz\*(Aq;
.Ve
.SS "class_to_file"
.IX Subsection "class_to_file"
.Vb 1
\& my $file = class_to_file \*(AqFoo::Bar\*(Aq;
.Ve
.PP
Convert a class name to a file.
.PP
.Vb 2
\& # "foo_bar"
\& class_to_file \*(AqFoo::Bar\*(Aq;
\&
\& # "foobar"
\& class_to_file \*(AqFOO::Bar\*(Aq;
\&
\& # "foo_bar"
\& class_to_file \*(AqFooBar\*(Aq;
\&
\& # "foobar"
\& class_to_file \*(AqFOOBar\*(Aq;
.Ve
.SS "class_to_path"
.IX Subsection "class_to_path"
.Vb 1
\& my $path = class_to_path \*(AqFoo::Bar\*(Aq;
.Ve
.PP
Convert class name to path, as used by \f(CW%INC\fR.
.PP
.Vb 2
\& # "Foo/Bar.pm"
\& class_to_path \*(AqFoo::Bar\*(Aq;
\&
\& # "FooBar.pm"
\& class_to_path \*(AqFooBar\*(Aq;
.Ve
.SS "decamelize"
.IX Subsection "decamelize"
.Vb 1
\& my $snakecase = decamelize $camelcase;
.Ve
.PP
Convert \f(CW\*(C`CamelCase\*(C'\fR string to \f(CW\*(C`snake_case\*(C'\fR and replace \f(CW\*(C`::\*(C'\fR with \f(CW\*(C`\-\*(C'\fR.
.PP
.Vb 2
\& # "foo_bar"
\& decamelize \*(AqFooBar\*(Aq;
\&
\& # "foo_bar\-baz"
\& decamelize \*(AqFooBar::Baz\*(Aq;
\&
\& # "foo_bar\-baz"
\& decamelize \*(Aqfoo_bar\-baz\*(Aq;
.Ve
.SS "decode"
.IX Subsection "decode"
.Vb 1
\& my $chars = decode \*(AqUTF\-8\*(Aq, $bytes;
.Ve
.PP
Decode bytes to characters with Encode, or return \f(CW\*(C`undef\*(C'\fR if decoding failed.
.SS "deprecated"
.IX Subsection "deprecated"
.Vb 1
\& deprecated \*(Aqfoo is DEPRECATED in favor of bar\*(Aq;
.Ve
.PP
Warn about deprecated feature from perspective of caller. You can also set the \f(CW\*(C`MOJO_FATAL_DEPRECATIONS\*(C'\fR environment
variable to make them die instead with Carp.
.SS "dumper"
.IX Subsection "dumper"
.Vb 1
\& my $perl = dumper {some => \*(Aqdata\*(Aq};
.Ve
.PP
Dump a Perl data structure with Data::Dumper.
.SS "encode"
.IX Subsection "encode"
.Vb 1
\& my $bytes = encode \*(AqUTF\-8\*(Aq, $chars;
.Ve
.PP
Encode characters to bytes with Encode.
.SS "extract_usage"
.IX Subsection "extract_usage"
.Vb 2
\& my $usage = extract_usage;
\& my $usage = extract_usage \*(Aq/home/sri/foo.pod\*(Aq;
.Ve
.PP
Extract usage message from the \s-1SYNOPSIS\s0 section of a file containing \s-1POD\s0 documentation, defaults to using the file this
function was called from.
.PP
.Vb 2
\& # "Usage: APPLICATION test [OPTIONS]\en"
\& extract_usage;
\&
\& =head1 SYNOPSIS
\&
\& Usage: APPLICATION test [OPTIONS]
\&
\& =cut
.Ve
.SS "getopt"
.IX Subsection "getopt"
.Vb 12
\& getopt
\& \*(AqH|headers=s\*(Aq => \emy @headers,
\& \*(Aqt|timeout=i\*(Aq => \emy $timeout,
\& \*(Aqv|verbose\*(Aq => \emy $verbose;
\& getopt $array,
\& \*(AqH|headers=s\*(Aq => \emy @headers,
\& \*(Aqt|timeout=i\*(Aq => \emy $timeout,
\& \*(Aqv|verbose\*(Aq => \emy $verbose;
\& getopt $array, [\*(Aqpass_through\*(Aq],
\& \*(AqH|headers=s\*(Aq => \emy @headers,
\& \*(Aqt|timeout=i\*(Aq => \emy $timeout,
\& \*(Aqv|verbose\*(Aq => \emy $verbose;
.Ve
.PP
Extract options from an array reference with Getopt::Long, but without changing its global configuration, defaults
to using \f(CW@ARGV\fR. The configuration options \f(CW\*(C`no_auto_abbrev\*(C'\fR and \f(CW\*(C`no_ignore_case\*(C'\fR are enabled by default.
.PP
.Vb 3
\& # Extract "charset" option
\& getopt [\*(Aq\-\-charset\*(Aq, \*(AqUTF\-8\*(Aq], \*(Aqcharset=s\*(Aq => \emy $charset;
\& say $charset;
.Ve
.SS "gunzip"
.IX Subsection "gunzip"
.Vb 1
\& my $uncompressed = gunzip $compressed;
.Ve
.PP
Uncompress bytes with IO::Compress::Gunzip.
.SS "gzip"
.IX Subsection "gzip"
.Vb 1
\& my $compressed = gzip $uncompressed;
.Ve
.PP
Compress bytes with IO::Compress::Gzip.
.SS "header_params"
.IX Subsection "header_params"
.Vb 1
\& my ($params, $remainder) = header_params \*(Aqone=foo; two="bar", three=baz\*(Aq;
.Ve
.PP
Extract \s-1HTTP\s0 header field parameters until the first comma according to \s-1RFC 5987\s0 <http://tools.ietf.org/html/rfc5987>.
Note that this function is \fB\s-1EXPERIMENTAL\s0\fR and might change without warning!
.SS "hmac_sha1_sum"
.IX Subsection "hmac_sha1_sum"
.Vb 1
\& my $checksum = hmac_sha1_sum $bytes, \*(Aqpassw0rd\*(Aq;
.Ve
.PP
Generate \s-1HMAC\-SHA1\s0 checksum for bytes with Digest::SHA.
.PP
.Vb 2
\& # "11cedfd5ec11adc0ec234466d8a0f2a83736aa68"
\& hmac_sha1_sum \*(Aqfoo\*(Aq, \*(Aqpassw0rd\*(Aq;
.Ve
.SS "html_attr_unescape"
.IX Subsection "html_attr_unescape"
.Vb 1
\& my $str = html_attr_unescape $escaped;
.Ve
.PP
Same as \*(L"html_unescape\*(R", but handles special rules from the \s-1HTML\s0 Living Standard <https://html.spec.whatwg.org>
for \s-1HTML\s0 attributes.
.PP
.Vb 2
\& # "foo=bar<est=baz"
\& html_attr_unescape \*(Aqfoo=bar<est=baz\*(Aq;
\&
\& # "foo=bar<est=baz"
\& html_attr_unescape \*(Aqfoo=bar<est=baz\*(Aq;
.Ve
.SS "html_unescape"
.IX Subsection "html_unescape"
.Vb 1
\& my $str = html_unescape $escaped;
.Ve
.PP
Unescape all \s-1HTML\s0 entities in string.
.PP
.Vb 2
\& # "<div>"
\& html_unescape \*(Aq<div>\*(Aq;
.Ve
.SS "humanize_bytes"
.IX Subsection "humanize_bytes"
.Vb 1
\& my $str = humanize_bytes 1234;
.Ve
.PP
Turn number of bytes into a simplified human readable format.
.PP
.Vb 2
\& # "1B"
\& humanize_bytes 1;
\&
\& # "7.5GiB"
\& humanize_bytes 8007188480;
\&
\& # "13GiB"
\& humanize_bytes 13443399680;
\&
\& # "\-685MiB"
\& humanize_bytes \-717946880;
.Ve
.SS "md5_bytes"
.IX Subsection "md5_bytes"
.Vb 1
\& my $checksum = md5_bytes $bytes;
.Ve
.PP
Generate binary \s-1MD5\s0 checksum for bytes with Digest::MD5.
.SS "md5_sum"
.IX Subsection "md5_sum"
.Vb 1
\& my $checksum = md5_sum $bytes;
.Ve
.PP
Generate \s-1MD5\s0 checksum for bytes with Digest::MD5.
.PP
.Vb 2
\& # "acbd18db4cc2f85cedef654fccc4a4d8"
\& md5_sum \*(Aqfoo\*(Aq;
.Ve
.SS "monkey_patch"
.IX Subsection "monkey_patch"
.Vb 2
\& monkey_patch $package, foo => sub {...};
\& monkey_patch $package, foo => sub {...}, bar => sub {...};
.Ve
.PP
Monkey patch functions into package.
.PP
.Vb 4
\& monkey_patch \*(AqMyApp\*(Aq,
\& one => sub { say \*(AqOne!\*(Aq },
\& two => sub { say \*(AqTwo!\*(Aq },
\& three => sub { say \*(AqThree!\*(Aq };
.Ve
.SS "punycode_decode"
.IX Subsection "punycode_decode"
.Vb 1
\& my $str = punycode_decode $punycode;
.Ve
.PP
Punycode decode string as described in \s-1RFC 3492\s0 <https://tools.ietf.org/html/rfc3492>.
.PP
.Vb 2
\& # "bücher"
\& punycode_decode \*(Aqbcher\-kva\*(Aq;
.Ve
.SS "network_contains"
.IX Subsection "network_contains"
.Vb 1
\& my $bool = network_contains $network, $address;
.Ve
.PP
Check that a given address is contained within a network in \s-1CIDR\s0 form. If the network is a single address, the
addresses must be equivalent.
.PP
.Vb 4
\& # True
\& network_contains(\*(Aq10.0.0.0/8\*(Aq, \*(Aq10.10.10.10\*(Aq);
\& network_contains(\*(Aq10.10.10.10\*(Aq, \*(Aq10.10.10.10\*(Aq);
\& network_contains(\*(Aqfc00::/7\*(Aq, \*(Aqfc::c0:ff:ee\*(Aq);
\&
\& # False
\& network_contains(\*(Aq10.0.0.0/29\*(Aq, \*(Aq10.10.10.10\*(Aq);
\& network_contains(\*(Aq10.10.10.12\*(Aq, \*(Aq10.10.10.10\*(Aq);
\& network_contains(\*(Aqfc00::/7\*(Aq, \*(Aq::1\*(Aq);
.Ve
.SS "punycode_encode"
.IX Subsection "punycode_encode"
.Vb 1
\& my $punycode = punycode_encode $str;
.Ve
.PP
Punycode encode string as described in \s-1RFC 3492\s0 <https://tools.ietf.org/html/rfc3492>.
.PP
.Vb 2
\& # "bcher\-kva"
\& punycode_encode \*(Aqbücher\*(Aq;
.Ve
.SS "quote"
.IX Subsection "quote"
.Vb 1
\& my $quoted = quote $str;
.Ve
.PP
Quote string.
.SS "scope_guard"
.IX Subsection "scope_guard"
.Vb 1
\& my $guard = scope_guard sub {...};
.Ve
.PP
Create anonymous scope guard object that will execute the passed callback when the object is destroyed.
.PP
.Vb 5
\& # Execute closure at end of scope
\& {
\& my $guard = scope_guard sub { say "Mojo!" };
\& say "Hello";
\& }
.Ve
.SS "secure_compare"
.IX Subsection "secure_compare"
.Vb 1
\& my $bool = secure_compare $str1, $str2;
.Ve
.PP
Constant time comparison algorithm to prevent timing attacks. The secret string should be the second argument, to avoid
leaking information about the length of the string.
.SS "sha1_bytes"
.IX Subsection "sha1_bytes"
.Vb 1
\& my $checksum = sha1_bytes $bytes;
.Ve
.PP
Generate binary \s-1SHA1\s0 checksum for bytes with Digest::SHA.
.SS "sha1_sum"
.IX Subsection "sha1_sum"
.Vb 1
\& my $checksum = sha1_sum $bytes;
.Ve
.PP
Generate \s-1SHA1\s0 checksum for bytes with Digest::SHA.
.PP
.Vb 2
\& # "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33"
\& sha1_sum \*(Aqfoo\*(Aq;
.Ve
.SS "slugify"
.IX Subsection "slugify"
.Vb 2
\& my $slug = slugify $string;
\& my $slug = slugify $string, $bool;
.Ve
.PP
Returns a \s-1URL\s0 slug generated from the input string. Non-word characters are removed, the string is trimmed and
lowercased, and whitespace characters are replaced by a dash. By default, non-ASCII characters are normalized to \s-1ASCII\s0
word characters or removed, but if a true value is passed as the second parameter, all word characters will be allowed
in the result according to unicode semantics.
.PP
.Vb 2
\& # "joel\-is\-a\-slug"
\& slugify \*(AqJoel is a slug\*(Aq;
\&
\& # "this\-is\-my\-resume"
\& slugify \*(AqThis is: my \- résumé! ☃ \*(Aq;
\&
\& # "this\-is\-my\-résumé"
\& slugify \*(AqThis is: my \- résumé! ☃ \*(Aq, 1;
.Ve
.SS "split_cookie_header"
.IX Subsection "split_cookie_header"
.Vb 1
\& my $tree = split_cookie_header \*(Aqa=b; expires=Thu, 07 Aug 2008 07:07:59 GMT\*(Aq;
.Ve
.PP
Same as \*(L"split_header\*(R", but handles \f(CW\*(C`expires\*(C'\fR values from \s-1RFC 6265\s0 <https://tools.ietf.org/html/rfc6265>.
.SS "split_header"
.IX Subsection "split_header"
.Vb 1
\& my $tree = split_header \*(Aqfoo="bar baz"; test=123, yada\*(Aq;
.Ve
.PP
Split \s-1HTTP\s0 header value into key/value pairs, each comma separated part gets its own array reference, and keys without
a value get \f(CW\*(C`undef\*(C'\fR assigned.
.PP
.Vb 2
\& # "one"
\& split_header(\*(Aqone; two="three four", five=six\*(Aq)\->[0][0];
\&
\& # "two"
\& split_header(\*(Aqone; two="three four", five=six\*(Aq)\->[0][2];
\&
\& # "three four"
\& split_header(\*(Aqone; two="three four", five=six\*(Aq)\->[0][3];
\&
\& # "five"
\& split_header(\*(Aqone; two="three four", five=six\*(Aq)\->[1][0];
\&
\& # "six"
\& split_header(\*(Aqone; two="three four", five=six\*(Aq)\->[1][1];
.Ve
.SS "steady_time"
.IX Subsection "steady_time"
.Vb 1
\& my $time = steady_time;
.Ve
.PP
High resolution time elapsed from an arbitrary fixed point in the past, resilient to time jumps if a monotonic clock is
available through Time::HiRes.
.SS "tablify"
.IX Subsection "tablify"
.Vb 1
\& my $table = tablify [[\*(Aqfoo\*(Aq, \*(Aqbar\*(Aq], [\*(Aqbaz\*(Aq, \*(Aqyada\*(Aq]];
.Ve
.PP
Row-oriented generator for text tables.
.PP
.Vb 2
\& # "foo bar\enyada yada\enbaz yada\en"
\& tablify [[\*(Aqfoo\*(Aq, \*(Aqbar\*(Aq], [\*(Aqyada\*(Aq, \*(Aqyada\*(Aq], [\*(Aqbaz\*(Aq, \*(Aqyada\*(Aq]];
.Ve
.SS "term_escape"
.IX Subsection "term_escape"
.Vb 1
\& my $escaped = term_escape $str;
.Ve
.PP
Escape all \s-1POSIX\s0 control characters except for \f(CW\*(C`\en\*(C'\fR.
.PP
.Vb 2
\& # "foo\e\ex09bar\e\ex0d\en"
\& term_escape "foo\etbar\er\en";
.Ve
.SS "trim"
.IX Subsection "trim"
.Vb 1
\& my $trimmed = trim $str;
.Ve
.PP
Trim whitespace characters from both ends of string.
.PP
.Vb 2
\& # "foo bar"
\& trim \*(Aq foo bar \*(Aq;
.Ve
.SS "unindent"
.IX Subsection "unindent"
.Vb 1
\& my $unindented = unindent $str;
.Ve
.PP
Unindent multi-line string.
.PP
.Vb 2
\& # "foo\enbar\enbaz\en"
\& unindent " foo\en bar\en baz\en";
.Ve
.SS "unquote"
.IX Subsection "unquote"
.Vb 1
\& my $str = unquote $quoted;
.Ve
.PP
Unquote string.
.SS "url_escape"
.IX Subsection "url_escape"
.Vb 2
\& my $escaped = url_escape $str;
\& my $escaped = url_escape $str, \*(Aq^A\-Za\-z0\-9\e\-._~\*(Aq;
.Ve
.PP
Percent encode unsafe characters in string as described in \s-1RFC 3986\s0 <https://tools.ietf.org/html/rfc3986>, the pattern
used defaults to \f(CW\*(C`^A\-Za\-z0\-9\e\-._~\*(C'\fR.
.PP
.Vb 2
\& # "foo%3Bbar"
\& url_escape \*(Aqfoo;bar\*(Aq;
.Ve
.SS "url_unescape"
.IX Subsection "url_unescape"
.Vb 1
\& my $str = url_unescape $escaped;
.Ve
.PP
Decode percent encoded characters in string as described in \s-1RFC 3986\s0 <https://tools.ietf.org/html/rfc3986>.
.PP
.Vb 2
\& # "foo;bar"
\& url_unescape \*(Aqfoo%3Bbar\*(Aq;
.Ve
.SS "xml_escape"
.IX Subsection "xml_escape"
.Vb 1
\& my $escaped = xml_escape $str;
.Ve
.PP
Escape unsafe characters \f(CW\*(C`&\*(C'\fR, \f(CW\*(C`<\*(C'\fR, \f(CW\*(C`>\*(C'\fR, \f(CW\*(C`"\*(C'\fR and \f(CW\*(C`\*(Aq\*(C'\fR in string, but do not escape Mojo::ByteStream
objects.
.PP
.Vb 2
\& # "<div>"
\& xml_escape \*(Aq<div>\*(Aq;
\&
\& # "<div>"
\& use Mojo::ByteStream qw(b);
\& xml_escape b(\*(Aq<div>\*(Aq);
.Ve
.SS "xor_encode"
.IX Subsection "xor_encode"
.Vb 1
\& my $encoded = xor_encode $str, $key;
.Ve
.PP
\&\s-1XOR\s0 encode string with variable length key.
.SH "SEE ALSO"
.IX Header "SEE ALSO"
Mojolicious, Mojolicious::Guides, <https://mojolicious.org>.