Curtis "Ovid" Poe > Package-Butcher-0.02 > Package::Butcher

Download:
Package-Butcher-0.02.tar.gz

Dependencies

Annotate this POD

View/Report Bugs
Module Version: 0.02   Source  

NAME ^

Package::Butcher - When you absolutely have to load that damned package.

ALPHA CODE ^

You've been warned. It also has an embarrassingly poor test suite. It was hacked together in an emergency while sitting in a hospital waiting for my daughter to be born. Sue me.

VERSION ^

Version 0.02

SYNOPSIS ^

    my $butcher = Package::Butcher->new(
        {
            package     => 'Dummy',
            do_not_load => [qw/Cannot::Load Cannot::Load2 NoSuch::List::MoreUtils/],
            predeclare  => 'uniq',
            subs => {
                this     => sub { 7 },
                that     => sub { 3 },
                existing => sub { 'replaced existing' },
            },
            method_chains => [
                [
                    'Cannot::Load' => qw/foo bar baz this that/ => sub {
                        my $args = join ', ' => @_;
                        return "end chain: $args";
                    },
                ],
            ],
        }
    );
    $butcher->use(@optional_import_list);

DESCRIPTION ^

Sometimes you need to load a module which won't otherwise load. Unit testing is a good reason. Unfortunately, some modules are just very, very difficult to load. This module is a nasty hack with a name designed to make this clear. It's here to provide a standard set of tools to let you load these problem modules.

USAGE ^

To use this module, let's consider the following awful module:

    package Dummy;

    use strict;
    use Cannot::Load;
    use NoSuch::List::MoreUtils 'uniq';
    use DBI;

    use base 'Exporter';
    our @EXPORT_OK = qw(existing);

    sub existing { 'should never see this' }

    # this strange construct forces a syntax error
    sub filter {
        uniq map {lc} split /\W+/, shift;
    }

    sub employees {
        my @connect =
          ( 'dbi:Pg:dbname=ourdb', '', '', { AutoCommit => 0 } );
        return DBI->connect(@connect)
          ->selectall_arrayref(
            'SELECT id, name, position FROM employees ORDER BY id');
    }

    sub recipes {
        my @connect = ( 'dbi:Pg:dbname=ourdb', '', '', { AutoCommit => 0 } );
        return DBI->connect(@connect)
          ->selectall_arrayref('SELECT id, name FROM recipes');
    } 

    1;

You probably cannot load this. You don't have Cannot::Load or NoSuch::List::MoreUtils available. What's worse, even if you try to stub them out and fake this, the employees and recipes methods might be frustrating. We'll use this as an example of how to use Package::Butcher.

METHODS ^

new

The constructor for Package::Butcher takes a hashref with several allowed keys. For example, the following will allow the Dummy package above to load:

    my $dummy = Package::Butcher->new({
        package => 'Dummy',
        do_not_load =>
          [qw/Cannot::Load NoSuch::List::MoreUtils DBI/],
        predeclare => 'uniq',
        subs       => {
            existing       => sub { 'replaced existing' },
            reverse_string => sub {
                my $arg = shift;
                return scalar reverse $arg;
            },
        },
        method_chains => [
            [
                'Cannot::Load' => qw/foo bar baz this that/ => sub {
                    my $args = join ', ' => @_;
                    return "end chain: $args";
                },
            ],
            [
                'DBI' => qw/connect selectall_arrayref/ => sub {
                    my $sql = shift;
                    return (
                        $sql =~ /\brecipes\b/
                        ? [
                            [qw/1 bob secretary/], 
                            [qw/2 alice ceo/],
                            [qw/3 ovid idiot/],
                          ]
                        : [ [ 1, 'Tartiflette' ], [ 2, 'Eggs Benedict' ], ];
                 },
             ],
        ],
    });

Here are the allowed keys to the constructor:

use

 my $butcher = Package::Butcher->new({ package ... });
 $butcher->use(@import_list);

Once constructed, this method will "use" the package in question. You may pass it the same import list that the package you're butchering takes. Note that if you override import, you're on your own.

require

 my $butcher = Package::Butcher->new({ package ... });
 $butcher->require;

Like use, but does a require.

AUTHOR ^

Curtis 'Ovid' Poe, <ovid at cpan.org>

BUGS ^

Please report any bugs or feature requests to bug-package-butcher at rt.cpan.org, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Package-Butcher. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.

SUPPORT ^

You can find documentation for this module with the perldoc command.

    perldoc Package::Butcher

You can also look for information at:

ACKNOWLEDGEMENTS ^

Flavio Glock for help with a parsing error.

LICENSE AND COPYRIGHT ^

Copyright 2011 Curtis 'Ovid' Poe.

This program is free software; you can redistribute it and/or modify it under the terms of either: the GNU General Public License as published by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

syntax highlighting: