Badger::Utils - various utility functions


Badger documentation Contained in the Badger distribution.

Index


Code Index:

NAME

Top

Badger::Utils - various utility functions

SYNOPSIS

Top

    use Badger::Utils 'blessed params';

    sub example {
        my $self   = shift;
        my $params = params(@_);

        if (blessed $self) {
            print "self is blessed\n";
        }
    }




DESCRIPTION

Top

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

Top

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 paramters 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 }

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...
    }

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

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);

AUTHOR

Top

Andy Wardley http://wardley.org/

COPYRIGHT

Top


Badger documentation Contained in the Badger distribution.

#========================================================================
#
# Badger::Utils
#
# DESCRIPTION
#   Module implementing various useful utility functions.
#
# AUTHOR
#   Andy Wardley   <abw@wardley.org>
#
#========================================================================

package Badger::Utils;

use strict;
use warnings;
use base 'Badger::Exporter';
use File::Path;
use Scalar::Util qw( blessed );
use Badger::Constants 'HASH PKG DELIMITER';
use Badger::Debug ':dump';
use overload;
use constant {
    UTILS  => 'Badger::Utils',
    CLASS  => 0,
    FILE   => 1,
    LOADED => 2,
};

our $VERSION  = 0.01;
our $DEBUG    = 0 unless defined $DEBUG;
our $ERROR    = '';
our $MESSAGES = { };
our $HELPERS  = {       # keep this compact in case we don't need to use it
    'Digest::MD5'       => 'md5 md5_hex md5_base64',
    'Scalar::Util'      => 'blessed dualvar isweak readonly refaddr reftype 
                                                        tainted weaken isvstring looks_like_number 
                                                        set_prototype',
    'List::Util'        => 'first max maxstr min minstr reduce shuffle sum',
    'List::MoreUtils'   => 'any all none notall true false firstidx 
                                                        first_index lastidx last_index insert_after 
                                                        insert_after_string apply after after_incl before 
                                                        before_incl indexes firstval first_value lastval 
                                                        last_value each_array each_arrayref pairwise 
                                                        natatime mesh zip uniq minmax',
    'Hash::Util'        => 'lock_keys unlock_keys lock_value unlock_value
                                                        lock_hash unlock_hash hash_seed',
    'Badger::Timestamp' => 'TS Timestamp Now',
    'Badger::Logic'     => 'LOGIC Logic',
};
our $DELEGATES;         # fill this from $HELPERS on demand


__PACKAGE__->export_any(qw(
    UTILS blessed is_object numlike textlike params self_params plural xprintf dotid
));

__PACKAGE__->export_fail(\&_export_fail);

# looks_like_number() is such a mouthful.  I prefer numlike() to go with textlike()
*numlike = \&Scalar::Util::looks_like_number;

sub _export_fail {    
    my ($class, $target, $symbol, $more_symbols) = @_;
    $DELEGATES ||= _expand_helpers($HELPERS);
    my $helper = $DELEGATES->{ $symbol } || return 0;
    require $helper->[FILE] unless $helper->[LOADED];
    $class->export_symbol($target, $symbol, \&{ $helper->[CLASS].PKG.$symbol });
    return 1;
}

sub _expand_helpers {
    # invert { x => 'a b c' } into { a => 'x', b => 'x', c => 'x' }
    my $helpers = shift;
    return {
        map {
            my $name = $_;                      # e.g. Scalar::Util
            my $file = module_file($name);      # e.g. Scalar/Util.pm
            map { $_ => [$name, $file, 0] }     # third item is loaded flag
            split(DELIMITER, $helpers->{ $name })
        }
        keys %$helpers
    }
}
        
sub is_object($$) {
    blessed $_[1] && $_[1]->isa($_[0]);
}

sub textlike($) {
    !  ref $_[0]                        # check if $[0] is a non-reference
    || blessed $_[0]                    # or an object with an overloaded
    && overload::Method($_[0], '""');   # '""' stringification operator
}

sub params {
    @_ && ref $_[0] eq HASH ? shift : { @_ };
}

sub self_params {
    (shift, @_ && ref $_[0] eq HASH ? shift : { @_ });
}

sub plural {
    my $name = shift;

    if ($name =~ /(ss|sh|ch|x)$/) {
        $name .= 'es';
    }
    elsif ($name =~ s/([^aeiou])y$//) {
        $name .= $1.'ies';
    }
    elsif ($name =~ /([^s\d\W])$/) {
        $name .= 's';
    }
    return $name;
}

sub module_file {
    my $file = shift;
    $file  =~ s[::][/]g;
    $file .= '.pm';
}

sub xprintf {
    my $format = shift;
    $format =~ s/<(\d+)(?::([#\-\+ ]?[\w\.]+))?>/'%' . $1 . '$' . ($2 || 's')/eg;
    sprintf($format, @_);
}

sub dotid {
    my $text = shift;       # munge $text to canonical lower case and dotted form
    $text =~ s/\W+/./g;     # e.g. Foo::Bar ==> Foo.Bar
    return lc $text;        # e.g. Foo.Bar  ==> foo.bar
}

sub _debug {
    print STDERR @_;
}

1;

__END__

# Local Variables:
# mode: perl
# perl-indent-level: 4
# indent-tabs-mode: nil
# End:
#
# vim: expandtab shiftwidth=4: