Badger::Utils
- NAME
- SYNOPSIS
- DESCRIPTION
- EXPORTABLE CONSTANTS
- UTILS
- EXPORTABLE FUNCTIONS
- Badger::Duration
- DURATION
- Duration()
- Badger::Filesystem
- FS
- VFS
- File()
- Dir()
- Bin()
- Cwd()
- Badger::Filter
- FILTER
- Filter()
- Badger::Logic
- LOGIC
- Logic()
- Badger::Timestamp
- TIMESTAMP
- TS
- Now()
- Timestamp()
- Badger::URL
- URL()
- Text Utility Functions
- alternates($text)
- camel_case($string) / CamelCase($string)
- dotid($text)
- inflect($n, $noun, $format, $none_word)
- numlike($item)
- permute_fragments($text)
- plural($noun)
- plurality($n, $noun)
- random_name($length,@data)
- textlike($item)
- wrap($text, $width, $indent)
- xprintf($format,@args)
- Hash Utility Functions
- extend($hash, $another_hash, $yet_another_hash, ...)
- merge($hash, $another_hash, $yet_another_hash, ...)
- hash_each($hash,$function)
- List Utility Functions
- list_each($list,$function)
- split_to_list($list)
- Object Utility Functions
- is_object($class,$object)
- Parameter Handling Functions
- params(@args)
- self_params(@args)
- odd_params(@_)
- URI Utility Functions
- join_uri(frag1, frag2, etc)
- resolve_uri(base, frag1, frag2, etc)
- Miscellanesou Utility Functions
- module_file($name)
- AUTHOR
- COPYRIGHT
use Badger::Utils 'blessed params'; sub example { my $self = shift; my $params = params(@_); if (blessed $self) { print "self is blessed\n"; } }
This module implements a number of utility functions. It also provides access to all of the utility functions in Scalar::Util, List::Util, List::MoreUtils, Hash::Util and Digest::MD5 as a convenience.
use Badger::Utils 'blessed reftype first max any all lock_hash md5_hex';
The single line of code shown here will import blessed
and
reftype
from Scalar::Util, first
and max
from List::Util, any
and
all
from List::Util, lock_hash
from Hash::Util, and md5_hex
from
Digest::MD5.
These modules are loaded on demand so there's no overhead incurred if you don't use them (other than a lookup table so we know where to find them).
Badger::Utils
can automatically load and export functions
defined in the Scalar::Util, List::Util, List::MoreUtils, Hash::Util and Digest::MD5 Perl modules.
use Badger::Utils 'blessed max md5_hex' # a rather contrived example if (blessed $some_ref) { print md5_hex(max @some_list); }
Badger::Utils
can also automatically load and export
functions and constants defined in various other Badger modules. For
example, you can use Badger::Utils
to load the Now() function from Badger::Timestamp.
use Badger::Utils 'Now'; print Now->year; # prints the current year
DURATION
An alias for Badger::Duration.
Duration()
A function to create a Badger::Duration object.
use Badger::Utils 'Duration'; my $duration = Duration('2 hours 20 minutes'); print $duration->seconds;
FS
An alias for Badger::Filesystem
.
VFS
An alias for Badger::Filesystem::Virtual
.
File()
A function for creating a Badger::Filesystem::File object.
my $f = File('filename'); print $filename->modified;
Dir()
A function for creating a Badger::Filesystem::Directory object.
Bin()
Returns a Badger::Filesystem::Directory object for the directory in which the current script is located. See Bin() in Badger::Filesystem.
Cwd()
Returns a Badger::Filesystem::Directory object for the current working directory. See Cwd() in Badger::Filesystem.
FILTER
An alias for Badger::Filter
.
Filter()
Function for returning a Badger::Filter object for filtering data.
my $filter = Filter( include => [ qr/beer/ ], exclude => [ 'root beer' ], ); my @matches = $filter->accept( 'beer', 'lite beer', 'root beer', 'soda' );
LOGIC
An alias for Badger::Logic
.
Logic()
Function for returning a Badger::Logic object for representing simple logical assertions.
my $logic = Logic('trusted and not banned'); my $person = { trusted => 1, banned => 0, }; if ($logic->evaluate($person)) { ... }
TIMESTAMP
An alias for Badger::Timestamp
.
TS
A shorter alias for Badger::Timestamp
.
Now()
Function for returning a Badger::Timestamp object representing the current date and time.
print Now->date;
Timestamp()
Function for creating a Badger::Timestamp object.
my $stamp = Timestamp('2013-03-19 16:20:00'); print $stamp->time; print $stamp->year;
URL()
Function for creating a Badger::URL object for representing and manipulating a URL.
my $url = URL('http://badgerpower.org/example?animal=badger'); print $url->path; print $url->query; print $url->server;
alternates($text)
This function is used internally by the permute_fragments() function. It
returns a reference to a list containing the alternates split from
$text
.
alternates('foo|bar'); # returns ['foo','bar'] alternates('foo'); # returns ['','bar']
If the $text
doesn't contain the |
character
then it is assumed to be an optional item. A list reference is returned
containing the empty string as the first element and the original
$text
string as the second.
camel_case($string) / CamelCase($string)
Converts a lower case string where words are separated by underscores
(e.g. like_this_example
) into CamelCase where each word is
capitalised and words are joined together (e.g.
LikeThisExample
).
According to Perl convention (and personal preference), we use the lower case form wherever possible. However, Perl's convention also dictates that module names should be in CamelCase. This function performs that conversion.
dotid($text)
The function returns a lower case representation of the text passed as an argument with all non-word character sequences replaced with dots.
print dotid('Foo::Bar'); # foo.bar
inflect($n, $noun, $format, $none_word)
This uses the plurality()
function to construct an
appropriate string listing the number $n
of
$noun
items.
inflect(0, 'package'); # no packages inflect(1, 'package'); # 1 package inflect(2, 'package'); # 2 packages
Or:
inflect($n, 'wo(men|man|men');
The third optional argument can be used to specify a format string for xprintf to generate the string. The default
value is %s %s
, expecting the number (or word 'no') as the
first parameter, followed by the relevant noun as the second.
inflect($n, 'item', 'There are <b>%s</b> %s in your basket');
The fourth optional argument can be used to provide a word other than
'no' to be used when $n
is zero.
inflect( $n, 'item', 'You have %s %s in your basket', 'none, none more' );
Please note that this function is intentionally limited. It's sufficient to generate simple headings, summary lines, etc., but isn't intended to be comprehensive or work in languages other than English.
numlike($item)
This is an alias to the looks_like_number()
function defined
in Scalar::Util.
permute_fragments($text)
This function permutes any optional or alternate fragments embedded in
parentheses. For example, Badger(X)
is permuted as
(Badger
, BadgerX
) and Badger(X|Y)
is permuted as (BadgerX
, BadgerY
).
permute_fragments('Badger(X)'); # Badger, BadgerX permute_fragments('Badger(X|Y)'); # BadgerX, BadgerY
Multiple fragments may be embedded. They are expanded in order from left to right, with the rightmost fragments changing most often.
permute_fragments('A(1|2):B(3|4)') # A1:B3, A1:B4, A2:B3, A2:B4
plural($noun)
The function makes a very naive attempt at pluralising the singular noun word passed as an argument.
If the $noun
word ends in ss
, sh
,
ch
or x
then es
will be added to
the end of it.
print plural('class'); # classes print plural('hash'); # hashes print plural('patch'); # patches print plural('box'); # boxes
If it ends in y
then it will be replaced with
ies
.
print plural('party'); # parties
In all other cases, s
will be added to the end of the word.
print plural('device'); # devices
It will fail miserably on many common words.
print plural('woman'); # womans FAIL! print plural('child'); # childs FAIL! print plural('foot'); # foots FAIL!
This function should only be used in cases where the singular noun
is known in advance and has a regular form that can be pluralised
correctly by the algorithm described above. For example, the Badger::Factory module allows you to
specify $ITEM
and $ITEMS
package variable to
provide the singular and plural names of the items that the factory
manages.
our $ITEM = 'person'; our $ITEMS = 'people';
If the singular noun is sufficiently regular then the $ITEMS
can be omitted and the plural
function will be used.
our $ITEM = 'codec'; # $ITEMS defaults to 'codecs'
In this case we know that codec
will pluralise correctly to
codecs
and can safely leave $ITEMS
undefined.
For more robust pluralisation of English words, you should use the Lingua::EN::Inflect module by Damian Conway. For further information on the difficulties of correctly pluralising English, and details of the implementation of Lingua::EN::Inflect, see Damian's paper "An Algorithmic Approach to English Pluralization" at http://www.csse.monash.edu.au/~damian/papers/HTML/Plurals.html
plurality($n, $noun)
This function can be used to construct the correct singular or plural
form for a given number, $n
, of a noun, $noun
in the English language. For nouns that pluralise regularly (i.e. via the
quick-and-dirty plural() function), the
following is sufficient:
plurality(0, 'package'); # packages plurality(1, 'package'); # package plurality(2, 'package'); # packages
For nouns that don't pluralise regularly, or where more complicated phrases should be constructed, the alternates for 0, 1 and 2 or more items can be specified in the format expected by permute_fragments().
plurality($n, 'women|woman|women'); # 0 women, 1 woman, 2 women plurality($n, 'wo(men|man|men'); # optimised form
random_name($length,@data)
Generates a random name of maximum length $length
using any
additional seeding data passed as @args
. If
$length
is undefined then the default value in
$RANDOM_NAME_LENGTH
(32) is used.
my $name = random_name(); my $name = random_name(64);
textlike($item)
Returns true if $item
is a non-reference scalar or an object
that has an overloaded stringification operator.
use Badger::Filesystem 'File'; use Badger::Utils 'textlike'; # Badger::Filesystem::File objects have overloaded string operator my $file = File('example.txt'); print $file; # example.txt print textlike $file ? 'ok' : 'not ok'; # ok
wrap($text, $width, $indent)
Simple subroutine to wrap $text
to a fixed
$width
, applying an optional indent of $indent
spaces. It uses a trivial algorithm which splits the text into words,
then rejoins them as lines. It has an additional hack to recognise the
literal sequence '\n' as a magical word indicating a forced newline
break. It must be specified as a separate whitespace delimited word.
print wrap('Foo \n Bar');
If anyone knows how to make Text::Wrap handle this, or knows of a better solution then please let me know.
xprintf($format,@args)
A wrapper around sprintf()
which provides some syntactic
sugar for embedding positional parameters.
xprintf('The <2> sat on the <1>', 'mat', 'cat'); xprintf('The <1> costs <2:%.2f>', 'widget', 11.99);
extend($hash, $another_hash, $yet_another_hash, ...)
This function merges the contents of several hash arrays into one. The first hash array will end up containing the keys and values of all the others.
my $one = { a => 10 }; my $two = { b => 20 }; extend($one, $two); # $one now contains a and b
If you want to create a new hash, simply pass an empty hash in as the first argument.
my $mixed = extend( { }, $one. $two );
You can also extend a hash array with named parameters.
extend( $mixed, c => 30, d => 40, );
You can mix and match the two calling conventions as long as any hash references come first.
extend( { }, $mixed, $a, $b, c => 30, d => 40, );
merge($hash, $another_hash, $yet_another_hash, ...)
This function is a version of extend() that merges nested hash arrays to any depth.
my $one = { a => 10, b => { c => 20, d => { e => 30, } }, }; my $two = { b => { d => { f => 40 }, g => 50, }, h => 60 }; merge($one, $two);
After merging $one
will contain:
{ a => 10, b => { c => 20, d => { e => 30, f => 40 } g => 50, }, h => 60 }
hash_each($hash,$function)
Iterates over each key/value pair in the hash array referenced by the
first argument, $hash
, calling the function passed as the
second argument, $function
.
The function is called with 3 arguments: a reference to the hash array, the key of the current item and the value.
hash_each( { a => 10, b => 20 }, sub { my ($hash, $key, $value) = @_; print "hash item $key is $value\n"; } );
list_each($list,$function)
Iterates over each item in the array referenced by the first argument,
$list
, calling the function passed as the second argument,
$function
.
The function is called with 3 arguments: a reference to the list, the index of the current index (from 0 to size-1) and the item in the list at that index.
list_each( [10,20,30], sub { my ($list, $index, $item) = @_; print "list item #$index is $item\n"; } );
split_to_list($list)
This splits a string of words separated by whitespace (and/or commas) into a list reference. The following are all valid and equivalent:
my $list = split_to_list("foo bar baz"); # => ['foo', 'bar', 'baz'] my $list = split_to_list("foo,bar,baz"); my $list = split_to_list("foo, bar, baz");
If the argument is already a list then it is returned unmodified.
is_object($class,$object)
Returns true if the $object
is a blessed reference which isa
$class
.
use Badger::Filesystem 'FS'; use Badger::Utils 'is_object'; if (is_object( FS => $object )) { # FS == Badger::Filesystem print $object, ' isa ', FS, "\n"; }
params(@args)
Method to coerce a list of named parameters to a hash array reference. If the first argument is a reference to a hash array then it is returned. Otherwise the arguments are folded into a hash reference.
use Badger::Utils 'params'; params({ a => 10 }); # { a => 10 } params( a => 10 ); # { a => 10 }
Pro Tip: If you're getting warnings about an "Odd number of elements in
anonymous hash" then try enabling debugging in
Badger::Utils
. To do this, add the following to the start of
your program before you've loaded Badger::Utils
:
use Badger::Debug modules => 'Badger::Utils'
When debugging is enabled in Badger::Utils
you'll get a full
stack backtrace showing you where the subroutine was called from. e.g.
Badger::Utils::self_params() called with an odd number of arguments: <undef> #1: Called from Foo::bar in /path/to/Foo/Bar.pm at line 210 #2: Called from Wam::bam in /path/to/Wam/Bam.pm at line 420 #3: Called from main in /path/to/your/script.pl at line 217
self_params(@args)
Similar to params() but also expects a
$self
reference at the start of the argument list.
use Badger::Utils 'self_params'; sub example { my ($self, $params) = self_params(@_); # do something... }
If you enable debugging in Badger::Utils
then you'll get a
stack backtrace in the event of an odd number of parameters being passed
to this function. See params() for further
details.
odd_params(@_)
This is an internal function used by params() and self_params() to report any attempt to
pass an odd number of arguments to either of them. It can be enabled by
setting $Badger::Utils::DEBUG
to a true value.
use Badger::Utils 'params'; $Badger::Utils::DEBUG = 1; my $hash = params( foo => 10, 20 ); # oops!
The above code will raise a warning showing the arguments passed and a stack backtrace, allowing you to easily track down and fix the offending code. Apart from obvious typos like the above, this is most likely to happen if you call a function or methods that returns an empty list. e.g.
params( foo => 10, bar => get_the_bar_value(), );
If get_the_bar_value()
returns an empty list then you'll end
up with an odd number of elements being passed to params()
.
You can correct this by providing undef
as an alternative
value. e.g.
params( foo => 10, bar => get_the_bar_value() || undef, );
The following functions are provided for very simple manipulation of URI paths. You should consider using the URI module for anything non-trivial.
join_uri(frag1, frag2, etc)
Joins the elements of a URI passed as arguments into a single URI.
use Contentity::Utils 'join_uri'; print join_uri('/foo', 'bar'); # /foo/bar
resolve_uri(base, frag1, frag2, etc)
The first argument is a base URI. The remaining argument(s) are joined
(via join_uri()) to construct a relative
URI. If the relative URI begins with /
then it is considered
absolute and is returned unchanged. Otherwise it is appended to the base
URI.
use Contentity::Utils 'resolve_uri'; print resolve_uri('/foo', 'bar/baz'); # /foo/bar/baz print resolve_uri('/foo', '/bar/baz'); # /bar/baz
Andy Wardley http://wardley.org/