Situation:
I have a module Foo::Quux::Bar
, living in ./Bar.pm
. I need to be able to unit test Bar. However, it is not advantageous due to circumstances beyond my control to set up a Foo/Quux directory structure.
So what I'd like to do is have some sort of unit_test_use routine that lets me grab Bar.pm and move/copy its functions into the local namespace(Note tha开发者_高级运维t Bar has a package Foo::Quux::Bar
specifier) for my testing pleasure.
Grubbing around in the Perl documentation has not helped me.
Assuming your Bar.pm exports its functions in the standard way, you can load it with require
and do the import manually:
BEGIN {
require 'Bar.pm'; # now the package Foo::Quux::Bar is set up
Foo::Quux::Bar->import;
};
But it's definitely worth looking into setting up the directory structure in the standard way, if you can.
The example below uses the following Bar.pm
:
package Foo::Quux::Bar;
use warnings;
use strict;
sub one { 1 }
sub two { "zwei" }
sub three { 0x3333 }
1;
In your test-bar
program, you can install a hook that will use the current directory's Bar.pm
with
#! /usr/bin/perl
use warnings;
use strict;
use File::Basename;
BEGIN {
sub find_bar {
my(undef,$name) = @_;
if (basename($name) eq "Bar.pm") {
open my $fh, "<", "./Bar.pm" or die "$0: open ./Bar.pm: $!";
$fh;
}
}
unshift @INC => \&find_bar;
}
Hooks in @INC
are documented in the perlfunc documentation for require
.
Now to import all subs, ignoring any import
in Foo::Quux::Bar
,
# fake use Foo::Quux::Bar
BEGIN {
require Foo::Quux::Bar;
{
no strict 'refs';
while (my($name,$glob) = each %Foo::Quux::Bar::) {
if (*{ $glob }{CODE}) {
*{ __PACKAGE__ . "::" . $name } = *{ $glob }{CODE};
}
}
}
}
Back out in the test code where the strict
pragma is enabled, we can
print map "$_\n", one, two, three;
and get the following output:
1 zwei 13107
Here's what I wrote:
sub import_module_into_main
{
my ($mod_name, $filename) = @_;
require $filename;
no strict;
foreach my $var ( keys( %{$mod_name . "::"}))
{
$main::{$var} = ${$mod_name. "::"}{$var};
}
}
Invoke with this: import_module_into_main("Foo::Quux::Bar", "Bar.pm")
.
精彩评论