NAME
Badger::Utils - various utility functions
SYNOPSIS
use Badger::Utils 'blessed params';
sub example {
my $self = shift;
my $params = params(@_);
if (blessed $self) {
print "self is blessed\n";
}
}
DESCRIPTION
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).
EXPORTABLE FUNCTIONS
Badger::Utils
can automatically load and export functions defined in the Scalar::Util, List::Util, List::MoreUtils, Hash::Util and Digest::MD5 Perl modules.
It also does the same for functions and constants defined in the Badger modules Badger::Timestamp (TS, Timestamp() and Now()) and Badger::Logic (LOGIC and Logic()).
For example:
use Badger::Utils 'Now';
print Now->year; # prints the current year
The following exportable functions are also defined in Badger::Utils
UTILS
Exports a UTILS
constant which contains the name of the Badger::Utils
class.
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";
}
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
numlike($item)
This is an alias to the looks_like_number()
function defined in Scalar::Util.
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,
);
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
module_file($name)
Returns the module name passed as an argument as a relative filesystem path suitable for feeding into require()
print module_file('My::Module'); # My/Module.pm
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.
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.
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
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);
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);
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('Badger(X)'); # Badger, BadgerX
permute('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('A(1|2):B(3|4)') # A1:B3, A1:B4, A2:B3, A2:B4
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.
AUTHOR
Andy Wardley http://wardley.org/
COPYRIGHT
Copyright (C) 1996-2009 Andy Wardley. All Rights Reserved.
This module is free software; you can redistribute it and/or modify it under the same terms as Perl itself.