NAME
Sub::Autostub - Stubbed OO and functional calls with logging.
SYNOPSIS
# functional
package Foo;
use Sub::Autostub verbose => 1;
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();
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.
Setting $Sub::Autostub::verbose = 1 or passing "verbose" with a true value with the "use" will add source line information to the output. For an example see the t/02.t for verbose use, t/03.t for non-verbose.
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.
Eventually, adding an argument to discern constructor-vs-class method (e.g., constructor => 'blah') will be the best way to handle this issue.
- 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).