Day the Second: Subclassing Badger::Utils

Badger::Utils Recap

Top Close Open

We looked yesterday at Badger::Utils which defines some useful utility functions. It also acts as a delegate to load utility functions from Scalar::Util and friends.

use Badger::Utils 'textlike params blessed 
                   max min any all md5_hex';

Creating Your Own Utility Library

Top Close Open

You can easily create your own libraries of utility functions by subclassing Badger::Utils.

package Your::Utils;
use base 'Badger::Utils';

our $EXPORT_ANY = 'random';

sub random {    # chosen by fair dice roll
    return 4;   # guaranteed to be random
}               # See http://xkcd.com/221/

1;

The first line defines the module name (Your::Utils) while the second declares it to be a subclass of the Badger::Utils base class. The $EXPORT_ANY package variable is use to specify which functions can be exported from this module. This is used by Badger::Exporter which is a base class of Badger::Utils.

In the utility module defined above we've got just one function, random(). Don't forget that Perl modules must always end with a true statement so we add the 1; line at the end to make it so.

Here's an example showing several functions being declared for export:

our $EXPORT_ANY = 'random more_random wildy_random';

This is syntactic sugar for the more verbose declaration:

our $EXPORT_ANY = [qw( random more_random wildy_random )];

Of course you'll also need to define those more_random() and wildly_random() functions somewhere in the module.

Using Your Library

Top Close Open

Now you can use your new utility library in your Perl programs. Specify the functions you want to import as arguments in the usual way.

use Your::Utils 'random';

Not only can you import the functions that you've defined in your module, but also all of those defined by the Badger::Utils base class and all those other modules that it can delegate to (Scalar::Util and co).

use Your::Utils qw( random textlike blessed any all );

The quote list construct qw( ... ) shown here can be replaced by a single string if you prefer:

use Your::Utils 'random textlike blessed any all';

Inheritance Just Works™ all the way up. If you want to you can subclass your utilities module to create another module. This will inherit everything from both Your::Module and Badger::Utils.

Multiple Inheritance

Top Close Open

You can also use multiple inheritance to construct a library that aggregates two or more other libraries. For example, let's say you've defined two utility modules called Your::Database::Utils and Your::Web::Utils. You might use them like this:

use Your::Web::Utils 'escape_html';
use Your::Database::Utils 'escape_sql';

Say you're writing a database-driven web site and you'll be needing to use both of these modules a lot of the time. You're far too lazy to type both the above lines of code in each of the modules that require them. Instead you can create a new composite library that inherits from both of them.

package Your::DataWeb::Utils;
use base qw( Your::Web::Utils Your::Database::Utils );
1;

That's it, job done. If you want to add any extra utility functions in here then go right ahead. You just need to remember to add in the $EXPORT_ANY declaration. When you use your new composite library you can import anything from either of the base classes (and any of their base classes, and so on).

use Your::DataWeb::Utils 'escape_html escape_sql';
Fork Me on Github