NAME
Util - Frequently Hacked Functions
DESCRIPTION
A cookbook of tasty functions for the terminally lazy, impatient and hubristic
TAGS
Rather than listing a group of functions by name, related subs can be imported using the tag syntax:
use Util qw(:tag);
The following tags have been defined:
:io
appendfile, atime, ctime, mtime, reader, readfile, writefile
:www
html, js, text, xml, xmlparse
:text
capitalize, commify, csv, ltrim, plural, rtrim, trim
:misc
any, apply, arrayref, coderef, find, hashref, scalarref, clone, id, respond, swap
:math
div, inf, infinity, isbig, isfloat, isinf, isnan, isneg, isnum, isuv
PUBLIC METHODS
any
usage
# return 0 or 1
my $flip = any();
# return a random element of the ARRAY or a random HASH key
my $el = any($hash_or_array_ref);
# return a randomly selected list of ARRAY elements / HASH keys
my @els = any($hash_or_array_ref, $number_of_items_to_pick);
# as above, but return the elements as an ARRAY ref (if
# $number_of_items_to_pick is greater than 1)
my $els = any($hash_or_array_ref, $number_of_items_to_pick);
# allow the same element to be picked multiple times
my @els = any($hash_or_array_ref, $number_of_items_to_pick,
$with_replacement);
my $els = any($hash_or_array_ref, $number_of_items_to_pick,
$with_replacement);
# return a random number between 0 and $integer_max inclusive
my $int = any($integer_max);
# return a random number between $integer_min and $integer_max
# inclusive
my $int = any($integer_min, $integer_max);
description
Returns a randomly chosen member of the referenced ARRAY, or a random key from the referenced HASH.
If the second argument is supplied, that number of items is chosen and returned as a list - defaults to 1.
If the third argument is supplied, items can be repeatedly chosen - defaults to 0 (false).
If the first argument is an integer x, an integer between 0 and x (inclusive) is returned.
If no argument is supplied, 0 or 1 is returned randomly.
If the first and second arguments are integers x and y, then an integer between x and y (inclusive) is returned.
any($ref, ...) does not modify the original HASH/ARRAY.
any($ref, $reflength) returns a shuffled list e.g.
# perform a non-destructive shuffle of the elements of $array
my @shuffled = any($array, $#$array + 1)
When supplied with a HASH or ARRAY ref, and a second argument (specifying the number of items to pick) greater than 1, the selected values are returned as a list in list context and an ARRAY ref in scalar context.
appendfile
usage
appendfile($file, $data, %args);
description
This is a simple wrapper for writefile()'s APPEND option.
Appends $data to the file whose path is specified by $file.
See writefile() for %args options.
apply
usage
my $result = apply $coderef, @optional_args;
# or
my $result = apply sub { do_something() }, @optional_args;
# or
my $result = apply \&Name::Space::sub, @optional_args;
description
Invokes the subroutine supplied as the first argument, passing any arguments in @optional_args as parameters.
Returns the result of the subroutine call.
arrayref
usage
do_something() if (arrayref $arg);
description
Returns a true value if $arg is a blessed or unblessed ARRAY reference.
Returns a false value otherwise.
atime
usage
my $atime = atime($file);
description
Returns the time (in seconds since the epoch) the specified file was last accessed.
capitalize
usage
my $capitalized = capitalize($string);
# or
my $capitalized = capitalize($string, @do_not_capitalize_these_words);
description
Initial-capitalizes $string i.e. any words (defined as consecutive characters between word-boundaries (\b)) in $string that don't already contain capitals are lowercased and their initials are uppercased.
Note: apostrophes are treated as word characters, so:
"There's more than one way to do it"
becomes:
"There's More Than One Way To Do It"
rather than:
"There'S More Than One Way To Do It"
Any arguments supplied after $string are treated as exceptions and left as is.
For non-trivial capitalization see the { case => 'highlight' } option of Damian Conway's Text::Autoformat.
In the absence of an explicit exception list, Util's capitalize() (and Text::Autoformat's { case => 'title' }) mechanically renders the text:
'what i did on my summer vacation in monterey'
as:
'What I Did On My Summer Vacation In Monterey'
Whereas Text::Autoformat's { case => 'highlight' } option offers the much more titular:
'What I Did on my Summer Vacation in Monterey'
clone
usage
use Util qw(clone);
$a = Foo->new();
$b = { alpha => 'beta', gamma => 'vlissides' };
tie %c, 'Foo::Bar';
$d = clone($a);
$e = clone($b);
$f = clone(\%c);
# or
my $node2 = {
name => 'node2',
children => [ $node3, $node4 ],
parent => weaken ($node1) # weaken() to avoid memory leak
};
# clone $node2 but preserve the original $node1 (rather than cloning
# through it all the way to the root)
my $clone = clone($node2, [ $node1 ]);
# or, equivalently
my $clone = clone($node2, [ $node2->{parent} ]);
description
clone() returns a recursive copy of its argument, which can be an arbitrary (scalar) type including nested HASH, ARRAY and reference types (including weak references), tied variables and objects.
To duplicate non-scalar types (e.g. lists, ARRAYs and HASHes), pass them to clone() by reference. e.g.
my $copy = clone (\@array);
# or
my %copy = %{ clone (\%hash) };
clone() takes an optional second argument: a reference to an ARRAY containing a list of exceptions i.e. values that should be 'passed-thru' verbatim. This is useful for, amongst other things, cloning nodes in a hierarchy without duplicating the structure all the way to the root.
For a slower, but more flexible solution see Storable's dclone().
coderef
usage
do_something() if (coderef $arg);
description
Returns a true value if $arg is a blessed or unblessed CODE reference.
Returns a false value otherwise.
commify
usage
my $pretty = commify($int);
description
Returns a reader-friendly representation of the supplied integer punctuated with commas at the customary thousands/millions (&c.) points.
Thus:
printf "%-9u\t%11s%s", $_, commify($_), $/
for (map { $_ x $_ } 1 .. 9);
prints:
1 1
22 22
333 333
4444 4,444
55555 55,555
666666 666,666
7777777 7,777,777
88888888 88,888,888
999999999 999,999,999
csv
usage
my $csv = csv($fields, $arrayref);
# or
my $csv = csv [ 'alpha', 'beta', 'gamma', 'vlissides' ],
[
{ alpha => 'fee', beta => 'fie', gamma => 'foe', vlissides => 'fum' },
{ alpha => 'foo', beta => 'bar', gamma => 'baz', vlissides => 'foobar' },
{ alpha => 'one', beta => 'two', gamma => 'three', vlissides => 'four' }
];
# or
my $csv = csv [ 'alpha', 'beta', 'gamma', 'vlissides' ],
[
[ qw(fee fie foe fum) ],
[ qw(foo bar baz foobar) ],
[ qw(one two three four) ],
];
# yields
"alpha","beta","gamma","delta"
"fee","fie","foe","fum"
"foo","bar","baz","foobar"
"one","two","three","four"
description
$fields: an ARRAY ref representing a list of field names
$arrayref: a reference to an ARRAY of HASH or ARRAY references
Returns either a string or (in list context) a list representing the rows of a CSV (Comma Separated Values) document generated from the supplied HASH or ARRAY refs and using the fields listed in $fields as the field names.
Field names and values are double quoted.
ctime
usage
my $ctime = ctime($file);
description
Returns the time (in seconds since the epoch) the specified file was created.
div
usage
my ($quotient, $remainder) = div ($numerator, $denominator);
# e.g.
my ($q, $r) = div (13, 3);
# $q = 4, $r = 1:
# 13 ($numerator) = 4 ($quotient) x 3 ($denominator) + 1 ($remainder)
description
Integer division operator: in list context, returns the quotient and remainder when the first operand ($numerator) is divided by the second ($denominator).
i.e.
$numerator = $quotient * $denominator + $remainder
In scalar context, returns just the quotient. To return the remainder, use %.
find
usage
my $index = find ($arrayref, $scalar)
# or
my $index = find ($arrayref, $scalar, $from)
description
Returns the offset of $scalar within $arrayref, with the first position denoted by 0.
$scalar can be a number, string or reference.
-1 is returned if the item is not found.
If the third argument is supplied, the search begins at that index (the offset is still calculated from the beginning of the ARRAY ref).
hashref
usage
do_something() if (hashref $arg);
description
Returns a true value if $arg is a blessed or unblessed HASH reference.
Returns a false value otherwise.
html
usage
html ($text);
# or
html ();
description
Returns $text with the 'text/html' Content-type header prefixed; or just the header if no $text is provided.
Prints the prefixed page out directly if called in void context.
id
usage
id()
description
Returns a quick 'n' dirty Unique Identifier. Uses $$ (amongst other things), so not necessarily reliable under SpeedyCGI, mod_perl &c.
infinity inf
usage
my $inf = infinity()
# or
my $inf = inf()
description
Perl 5.8 claims to support infinity natively, but falls short on many platforms. This utility function is a trivial wrapper for the Swiss-Army $Inf provided by Math::Complex, which jumps through every possible hoop to deliver a high-quality infinity product for your reckoning pleasure.
isnum
usage
isnum ($val)
description
Returns a nonzero value (indicating the numeric type) if $val is a number.
The numeric types are a conjunction of the following flags:
0x01 IS_NUMBER_IN_UV (number within UV range - maybe not int)
0x02 IS_NUMBER_GREATER_THAN_UV_MAX (the pointed-to UV is undefined)
0x04 IS_NUMBER_NOT_INT (saw . or E notation)
0x08 IS_NUMBER_NEG (leading minus sign)
0x10 IS_NUMBER_INFINITY (this is big)
0x20 IS_NUMBER_NAN (this is not)
Rather than obliging the user to twiddle with bits, the following flavours of isnum (corresponding to the flags above) are also available:
isint
isuv
isbig
isfloat
isneg
isinf
isnan
isint returns -1 if its operand is a negative integer, 1 if it's a positive integer and 0 otherwise.
The others always return 1 or 0.
js
usage
js ($text);
# or
js ();
description
Returns the JavaScript in $text with the 'application/x-javascript' Content-type header prefixed; or just the header if no $text is provided.
Prints the prefixed page out directly if called in void context
ltrim
usage
my $trimmed = ltrim ($string);
description
Returns a copy of $string with whitespace removed from the beginning.
mtime
usage
my $mtime = mtime($file);
description
Returns the time (in seconds since the epoch) the specified file was last modified.
plural
usage
my $plural = plural($stem, $count);
# or
my $plural = plural($stem, $count, $plural);
description
Plural() takes a singular word or word-stem as an argument; it evaluates $count to see if it is equal to 1; if it is, $stem is returned unchanged; otherwise $stem is pluralised by adding $plural, or 's' if $plural hasn't been supplied.
Thus:
my $plural = plural('error', $error);
will return:
'errors' if $error == 0
'error' if $error == 1
'errors' if $error > 1
This simple implementation does not support irregular plurals that modify the stem. For solutions to that, and indeed, most other non-trivial pluralization problems, the reader is referred to Damian Conway's Lingua::EN::Inflect.
reader
usage
my $source = '';
my $read = reader($path, IRS => '...', CHOMP => 1);
while ($read->(\$source)) {
do_something_with($source);
}
# or
while ($read->()) { # implied target: $_
do_something_with($_);
}
description
This method implements a generator/continuation interface to the fine art of file slurpage. It provides a private (lexically scoped) filehandle and an associated file reader (in the form of a closure).
This closure should be called with a reference to the variable one wishes to be assigned the next line from the file.
If no argument is supplied then $_ is assumed to be the target.
The generator yields true while the file is slurping, and undef thereafter.
The file is automatically closed either when the file has been read, or the closure goes out of scope - whichever comes first.
readfile
description
Swiss-Army Slurp
usage
# vanilla
readfile($path); # print the file
# or
my $file = readfile($path);
# handle warnings/fatal errors
my $file = readfile($path, WARN => \&my_warn, DIE => sub { die @_ });
# lines
my @file = readfile($path);
# set Input Record Separator
my @file = readfile($path, IRS => '...');
# strip Input Record Separator from result
my @file = readfile($path, IRS => '...', CHOMP => 1);
# all together now...
my $file = readfile(
$path,
WARN => $warn,
DIE => $die,
IRS => '...',
CHOMP => 1);
# synonyms for IRS => DELIM, SPLIT, DELIMITER
respond
usage
respond ($scalar)
respond (@list)
description
respond() performs a context-sensitive return:
In void context the supplied arguments are printed.
In scalar context it returns:
the supplied argument if there's only one
the concatenation of its arguments if there's more than one
In list context it returns the arguments unchanged.
rtrim
usage
my $trimmed = rtrim ($string);
description
Returns a copy of $string with whitespace removed from the end.
scalarref
usage
do_something() if (scalarref $arg);
description
Returns a true value if $arg is a blessed or unblessed SCALAR reference.
Returns a false value otherwise.
squash
usage
my $text = squash ($string);
description
Returns a 'flat' copy of $string i.e. with initial and terminal whitespace removed and one or more internal whitespace characters (including carriage-returns and newlines) squashed into a single space.
swap
usage
swap($x, $y);
description
Sets the value of $x to $y and vice-versa.
swap() is prototyped to receive its arguments by reference, and modifies its arguments in place like chop, chomp &c.
No value is returned
text
usage
text ($text);
# or
text ();
description
Returns $text with the 'text/plain' Content-type header prefixed; or just the header if no $text is provided.
Prints the prefixed page out directly if called in void context.
trim
usage
my $trimmed = trim ($string);
description
Returns a copy of $string with whitespace removed from the beginning and end; in addition, consecutive internal spaces are squashed to a single space.
urlize
usage:
my $url = urlize('Foo: BAR baz'); # returns 'foo_bar_baz'
# or
my $url = urlize('Foo - BAR - baz', 'html'); # returns 'foo_bar_baz.html'
description:
makes its text argument URL-friendly
Returns the first argument lowercased with any consecutive non-alphanumeric characters replaced by an underscore.
If the optional second argument is provided, this is appended as an extension prefixed by '.'
writefile
usage
writefile($file, $data, %args);
description
Write $data to filename $file. In theory, additional herbs and spices are specified as a list of pairs, in the same manner as readfile (and reader).
In practice, only APPEND => 1 for append (as opposed to truncate) and/or 'MODE' => $mode (to roll your own file access mode) are currently defined.
xml
usage
xml ($text);
# or
xml ();
description
Returns (optional) $text with the 'text/xml' Content-type header prefixed; or just the header if no $text is provided.
Prints the prefixed page out directly if called in void context.
xmlparse
usage
xmlparse ($parser, $xml_path_or_data);
description
Convenience wrapper for XML::Parser (or XML::Parser::Expat - or indeed any parser that supports parse() and parsefile()) that is agnostic with regard to whether $xml is a file/filehandle or raw XML text.
The $parser should be prefabricated according to taste.
BUGS
clone() currently segfaults if it encounters a Regex object
SEE ALSO
Scalar::Util, List::Util, Clone, Storable, File::Butler, Toolbox
AUTHOR
chocolateboy: <chocolate.boy@email.com>
COPYRIGHT
Copyright (c) 2001-2003, chocolateboy.
This module is free software. It may be used, redistributed and/or modified under the same terms as Perl itself.
1 POD Error
The following errors were encountered while parsing the POD:
- Around line 1426:
=cut found outside a pod block. Skipping to next block.