NAME
Sub::Stubber - Self-monkeypatch your on demand.
SYNOPSIS
package Expensive;
use Sub::Stubber;
use base qw(Sub::Stubber Exporter);
our @EXPORT = qw(expensive_1 expensive_2);
Sub::Stubber->regstubs(@EXPORT);
Sub::Stubber->add_trigger(import => '__USE_STUBS__');
Sub::Stubber->add_trigger(env => EXPENSIVE_USE_STUBS);
sub expensive_1 ($$) {
sleep(100);
}
sub expensive_2 (@) {
sleep(200);
}
Meanwhile, in calling code:
use Expensive qw(__USE_STUBS__);
expensive_1 'foo', 'bar'; #returns immediately
my @l;
expensive_2 @l; #returns immediately
From the command line:
EXPENSIVE_USE_STUBS=1 perl -MExpensive -e 'expensive_1 1,2'
DESCRIPTION
Sub::Stubber
allows for modules to conveniently change their containing functions into stubs. This is useful for code which by default does expensive operations, but which may not be desired for one-off cases, such as test environments or scripts - or in cases where calling code knows that those functions will never need to return anything significant.
The 'stubification' of the modules is hard. This does not attempt to merely export stubbed functions to calling code, but will override the actual functions with their stubbed versions, so exported, fully qualified and intra-package calls to these functions will all use the stubs instead.
If you would like to see a more export-oriented module, have a look at Sub::Exporter.
This module has no exports of its own, and its functionality is available via inheritance and/or package methods:
Sub::Stubber->regstubs(...)
Register one or more sub specifications to be used in conjunction with the calling package.
A stub specification can either be a simple name, or a hash reference.
- String
-
Sub::Stubber->regstubs('foo_function');
When strings are used, a function returning undef will be triggered for it.
- Hash Reference
-
Sub::Stubber->regstubs( { get_everything => 42 } ); Sub::Stubber->regstubs( { naive_implementation => sub { rand(10) } } );
Hash reference specifications can contain one or more key-value pairs. The keys are the function names to be replaced. The value can either be a simple scalar, or a
CODE
reference.In the case of the former, the value is returned as is from the function. In the case of the latter, the
CODE
reference itself is interpreted to be the replacement function. [ If you need to have a function which itself actually returns a function, you should provide aCODE
reference which does just that ].
Prototypes are fetched from the original function and applied to the new one.
It is also possible to specify multiple definitions in a single call, thus, the following is perfectly valid:
Sub::Stubber->regstubs(
'foo_function',
{
get_everything => 42,,
naive_implementation => sub { rand(10) }
}
);
Sub::Stubber->add_trigger(trigger_type, trigger_name)
Modules need to know when they need to generate a trigger function.
The trigger_type
argument specifies what type of trigger should be added, and trigger_name
is the name of that trigger.
Note that triggers only have meaning within Sub::Stubber
's import function, but should work as a standalone in a future release.
The triggers provided are:
env
-
Check the environment to see if a specific flag
trigger_name
is set to true. import
-
Check arguments passed to
import
for a token matchingtrigger_name
.
Sub::Stubber->mkstubs(extra stub specifiers)
'Stubbify' the functions registered with regstubs
and/or additional stub specifiers passed as arguments to mkstubs
.
This does not do checking on environment variables, and should be used from your own import
function, if Sub::Stubber
's import isn't sufficient.
INHERITING
You can inherit from Sub::Stubber
. Inheriting provides an import method which works with Exporter, and allows it to scan special import-time tokens and/or environment variables specifying whether functions should be stubbified.
If you choose to inherit from this module, ensure that Sub::Stubber
's import
gets called first by placing it at the beginning of your module's @ISA
.
Thus:
our @ISA = qw(Sub::Stubber Exporter);
TODO
Make this module more friendly for code which doesn't like to inherit it.
AUTHOR & COPYRIGHT
Copyright (C) 2012 M. Nunberg
You may use and distribute this software under the same terms and conditions as Perl itself.