NAME

Sub::Autostub - Stubbed OO and functional calls with logging.

SYNOPSIS

# functional

package Foo;

use Sub::Autostub;

frobnicate foo => 1, bar => 2;

# OO with constructor and methods stubbed

package Bar;

use base qw( Sub::Autostub );

my $obj = Bar->construct( -foo => 'bar', -bletch => 'blort' );

$obj->frobnicate( bar => 'foo' );

# OO with the serving package shown

package Base;

use Sub::Autostub;

package Derived;

use base qw( Base );

...

# this logs the call as being Base::construct if 
# "construct" is still stubbed in both classes.

my $obj = Derived->construct();


# sometimes it's handy to get something other 
# than 1 back from all of the calls. use makes 
#
# sets $a to { this => 'test' } verbosely.

use Sub::Autostub
(
    frobnicate  => { this => 'test' }
);

$Sub::Autostub->verbose( 1 );

my $a = frobnicate foo => 1;

# no import mechanism for use base...
# $returnz->{ class }{ method } stores the return
# value. in this case allowing testify to return
# zero but true.

use base Sub::Autostub;

$Sub::Autostub::return_values->
(
    {
        foo => 0E0,

        bar => 'bletch',
    }
);

$verbose->( 1 );

# foo and bar now return 0E0 and 'bletch' verbosely.

$obj->foo;

$obj->bar;

DESCRIPTION

During development the entire contents of some modules may not be known. In this case stubbing the functions or methods is helpful. Sub::Autostub simplifies this process with an AUTOLOAD that logs the subroutine being called and the arguments passed via Data::Dumper.

OO calls without a reference as the first argument the call are assumed to be constructor's and return a minimal object (see KNOWN ISSUES for more on this).

If the module is included via "use" then it exports an AUTOLOAD into the caller's namespace. This will log the calls as "Stub Package::Name:" with the package value assigned to the use-ing package. This is useful for functional programming or in cases where knowing which of multiple packages is resolved to handle a task in OO.

If the module is added via "use base" then the built-in AUTOLOAD will be called. This will return a blessed scalar containing the name of the package if the first argument is not a reference, otherwise it returns 1. The former case is logged as "Stub construct $package:" the latter as "Sub method $name:" each with the arguments listed via Data::Dumper.

Specific Return Values

There are times when returning 1 for all subs just doesn't cut it. A fixed value can be returned for specific sub's (even if they don't yet exist) by passing in a hash of sub names and their returns via:

# Functinal

use Stub::Autostub
qw( foo => 0E0, bar => 'Your Message Here' );

or

# OO or functional

$Sub::Autostub::return_values->
(
    foo => 0E0,
    bar => 'Your Message Here'
);

The call to return_values will pass back a hash reference, which allows for one-time return values via local:

# test something...

my $valuz = $Sub::Autostub::return_values->( foo => 1 );

...

sub test_reply
{
    local $valuz->{ reply } => 'The moon! the sun: it is not moonlight now.';

    $katharina->reply( 'how bright and goodly shines the moon!' );
}

This could be handy for some situations with Test::* where controling the return values is useful for testing handling of returned error codes.

Verbosity

The verbosity of logging output is controlled via:

$Sub::Autostub::verbose->( $level )

with the levels of 0 (silent), 1 (log call), 2 (log call & caller), or 3 (log call, caller, & arguments).

The default level is 1.

KNOWN ISSUES

All class methods default to a constructor.

If the first argument in OO code (i.e., via use base) is not a referent then it is assumed to be a constructor. This is less painful than it seems at first since class methods are usually few, coded early, and can be explicitly stubbed easily via code or setting explicit return values.

The default object is simplistic.

This is also less painful than it looks at first since a workable constructor is the first thing people usually add to a class. After that the AUTOLOAD here is never called and the only issue is class methods (see previous entry).

Fix for this is either adding an explicit stub constructor early or setting the return value for the constructor to some more useful value via $Sub::Autostub::return_values.

COPYRIGHT

Copyright (C) 2005, Steven Lembark. This code is released under the same terms as Perl-5.8.0 itself.

AUTHOR

Steven Lembark <lembark@wrkhors.com>