summaryrefslogtreecommitdiff
path: root/cpan/Module-Load
diff options
context:
space:
mode:
authorNicholas Clark <nick@ccl4.org>2009-09-26 14:41:29 +0100
committerNicholas Clark <nick@ccl4.org>2009-09-26 14:51:33 +0100
commit1ac05d83359ab0b4e03b39df1d104eb71a8437cf (patch)
treeabcc16d42bebc7709de2e2e7d9b4635c3a69be0a /cpan/Module-Load
parent2ad3fd79fc9c36127e4a72f731e2784799de0b2f (diff)
downloadperl-1ac05d83359ab0b4e03b39df1d104eb71a8437cf.tar.gz
Move Module::Load from ext/ to cpan/
Diffstat (limited to 'cpan/Module-Load')
-rw-r--r--cpan/Module-Load/lib/Module/Load.pm181
-rw-r--r--cpan/Module-Load/t/01_Module-Load.t52
-rw-r--r--cpan/Module-Load/t/to_load/LoadIt.pm3
-rw-r--r--cpan/Module-Load/t/to_load/LoadMe.pl1
-rw-r--r--cpan/Module-Load/t/to_load/Must/Be/Loaded.pm3
-rw-r--r--cpan/Module-Load/t/to_load/TestModule.pm31
-rw-r--r--cpan/Module-Load/t/to_load/ToBeLoaded1
-rw-r--r--cpan/Module-Load/t/to_load/config_file30
8 files changed, 302 insertions, 0 deletions
diff --git a/cpan/Module-Load/lib/Module/Load.pm b/cpan/Module-Load/lib/Module/Load.pm
new file mode 100644
index 0000000000..08f64b2b2c
--- /dev/null
+++ b/cpan/Module-Load/lib/Module/Load.pm
@@ -0,0 +1,181 @@
+package Module::Load;
+
+$VERSION = '0.16';
+
+use strict;
+use File::Spec ();
+
+sub import {
+ my $who = _who();
+
+ { no strict 'refs';
+ *{"${who}::load"} = *load;
+ }
+}
+
+sub load (*;@) {
+ my $mod = shift or return;
+ my $who = _who();
+
+ if( _is_file( $mod ) ) {
+ require $mod;
+ } else {
+ LOAD: {
+ my $err;
+ for my $flag ( qw[1 0] ) {
+ my $file = _to_file( $mod, $flag);
+ eval { require $file };
+ $@ ? $err .= $@ : last LOAD;
+ }
+ die $err if $err;
+ }
+ }
+
+ ### This addresses #41883: Module::Load cannot import
+ ### non-Exporter module. ->import() routines weren't
+ ### properly called when load() was used.
+ { no strict 'refs';
+ my $import;
+ if (@_ and $import = $mod->can('import')) {
+ unshift @_, $mod;
+ goto &$import;
+ }
+ }
+}
+
+sub _to_file{
+ local $_ = shift;
+ my $pm = shift || '';
+
+ my @parts = split /::/;
+
+ ### because of [perl #19213], see caveats ###
+ my $file = $^O eq 'MSWin32'
+ ? join "/", @parts
+ : File::Spec->catfile( @parts );
+
+ $file .= '.pm' if $pm;
+
+ ### on perl's before 5.10 (5.9.5@31746) if you require
+ ### a file in VMS format, it's stored in %INC in VMS
+ ### format. Therefor, better unixify it first
+ ### Patch in reply to John Malmbergs patch (as mentioned
+ ### above) on p5p Tue 21 Aug 2007 04:55:07
+ $file = VMS::Filespec::unixify($file) if $^O eq 'VMS';
+
+ return $file;
+}
+
+sub _who { (caller(1))[0] }
+
+sub _is_file {
+ local $_ = shift;
+ return /^\./ ? 1 :
+ /[^\w:']/ ? 1 :
+ undef
+ #' silly bbedit..
+}
+
+
+1;
+
+__END__
+
+=pod
+
+=head1 NAME
+
+Module::Load - runtime require of both modules and files
+
+=head1 SYNOPSIS
+
+ use Module::Load;
+
+ my $module = 'Data:Dumper';
+ load Data::Dumper; # loads that module
+ load 'Data::Dumper'; # ditto
+ load $module # tritto
+
+ my $script = 'some/script.pl'
+ load $script;
+ load 'some/script.pl'; # use quotes because of punctuations
+
+ load thing; # try 'thing' first, then 'thing.pm'
+
+ load CGI, ':standard' # like 'use CGI qw[:standard]'
+
+
+=head1 DESCRIPTION
+
+C<load> eliminates the need to know whether you are trying to require
+either a file or a module.
+
+If you consult C<perldoc -f require> you will see that C<require> will
+behave differently when given a bareword or a string.
+
+In the case of a string, C<require> assumes you are wanting to load a
+file. But in the case of a bareword, it assumes you mean a module.
+
+This gives nasty overhead when you are trying to dynamically require
+modules at runtime, since you will need to change the module notation
+(C<Acme::Comment>) to a file notation fitting the particular platform
+you are on.
+
+C<load> eliminates the need for this overhead and will just DWYM.
+
+=head1 Rules
+
+C<load> has the following rules to decide what it thinks you want:
+
+=over 4
+
+=item *
+
+If the argument has any characters in it other than those matching
+C<\w>, C<:> or C<'>, it must be a file
+
+=item *
+
+If the argument matches only C<[\w:']>, it must be a module
+
+=item *
+
+If the argument matches only C<\w>, it could either be a module or a
+file. We will try to find C<file> first in C<@INC> and if that fails,
+we will try to find C<file.pm> in @INC.
+If both fail, we die with the respective error messages.
+
+=back
+
+=head1 Caveats
+
+Because of a bug in perl (#19213), at least in version 5.6.1, we have
+to hardcode the path separator for a require on Win32 to be C</>, like
+on Unix rather than the Win32 C<\>. Otherwise perl will not read its
+own %INC accurately double load files if they are required again, or
+in the worst case, core dump.
+
+C<Module::Load> cannot do implicit imports, only explicit imports.
+(in other words, you always have to specify explicitly what you wish
+to import from a module, even if the functions are in that modules'
+C<@EXPORT>)
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Jonas B. Nielsen for making explicit imports work.
+
+=head1 BUG REPORTS
+
+Please report bugs or other issues to E<lt>bug-module-load@rt.cpan.org<gt>.
+
+=head1 AUTHOR
+
+This module by Jos Boumans E<lt>kane@cpan.orgE<gt>.
+
+=head1 COPYRIGHT
+
+This library is free software; you may redistribute and/or modify it
+under the same terms as Perl itself.
+
+
+=cut
diff --git a/cpan/Module-Load/t/01_Module-Load.t b/cpan/Module-Load/t/01_Module-Load.t
new file mode 100644
index 0000000000..0aaed74be0
--- /dev/null
+++ b/cpan/Module-Load/t/01_Module-Load.t
@@ -0,0 +1,52 @@
+### Module::Load test suite ###
+BEGIN {
+ if( $ENV{PERL_CORE} ) {
+ chdir '../lib/Module/Load' if -d '../lib/Module/Load';
+ unshift @INC, '../../..';
+ }
+}
+
+BEGIN { chdir 't' if -d 't' }
+
+use strict;
+use lib qw[../lib to_load];
+use Module::Load;
+use Test::More 'no_plan';
+
+### test loading files & modules
+{ my @Map = (
+ # module flag diagnostic
+ [q|Must::Be::Loaded|, 1, 'module'],
+ [q|LoadMe.pl|, 0, 'file' ],
+ [q|LoadIt|, 1, 'ambiguous module' ],
+ [q|ToBeLoaded|, 0, 'ambiguous file' ],
+ );
+
+ for my $aref (@Map) {
+ my($mod, $flag, $diag) = @$aref;
+
+ my $file = Module::Load::_to_file($mod, $flag);
+
+ eval { load $mod };
+
+ is( $@, '', qq[Loading $diag '$mod' $@] );
+ ok( defined($INC{$file}), qq[ '$file' found in \%INC] );
+ }
+}
+
+### Test importing functions ###
+{ my $mod = 'TestModule';
+ my @funcs = qw[func1 func2];
+
+ eval { load $mod, @funcs };
+ is( $@, '', qq[Loaded exporter module '$mod'] );
+
+ ### test if import gets called properly
+ ok( $mod->imported, " ->import() was called" );
+
+ ### test if functions get exported
+ for my $func (@funcs) {
+ ok( $mod->can($func), " $mod->can( $func )" );
+ ok( __PACKAGE__->can($func), " we ->can ( $func )" );
+ }
+}
diff --git a/cpan/Module-Load/t/to_load/LoadIt.pm b/cpan/Module-Load/t/to_load/LoadIt.pm
new file mode 100644
index 0000000000..63874fd443
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/LoadIt.pm
@@ -0,0 +1,3 @@
+$VERSION = 1;
+
+1; \ No newline at end of file
diff --git a/cpan/Module-Load/t/to_load/LoadMe.pl b/cpan/Module-Load/t/to_load/LoadMe.pl
new file mode 100644
index 0000000000..6912615643
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/LoadMe.pl
@@ -0,0 +1 @@
+1; \ No newline at end of file
diff --git a/cpan/Module-Load/t/to_load/Must/Be/Loaded.pm b/cpan/Module-Load/t/to_load/Must/Be/Loaded.pm
new file mode 100644
index 0000000000..46de6d5e14
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/Must/Be/Loaded.pm
@@ -0,0 +1,3 @@
+$VERSION = 0.01;
+
+1; \ No newline at end of file
diff --git a/cpan/Module-Load/t/to_load/TestModule.pm b/cpan/Module-Load/t/to_load/TestModule.pm
new file mode 100644
index 0000000000..ffc5ec98f5
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/TestModule.pm
@@ -0,0 +1,31 @@
+package TestModule;
+
+use strict;
+require Exporter;
+use vars qw(@EXPORT @EXPORT_OK @ISA $IMPORTED);
+
+@ISA = qw(Exporter);
+@EXPORT = qw(func2);
+@EXPORT_OK = qw(func1);
+
+### test if import gets called properly
+sub import { $IMPORTED = 1;
+ ### this breaks on 5.8.[45] which have a bug with goto's losing
+ ### arguments in @_. This is the cause of the 0.14 tester failures
+ ### under 5.8.[45]. The bug is NOT in exporter, but core perl:
+ ### http://testers.cpan.org/show/Module-Load.html
+ #goto &Exporter::import;
+
+ ### instead, use the undocumented, but widely used $ExportLevel
+ ### which will make sure we pass all arguments, and even works
+ ### on buggy 5.8.[45]
+ do { local $Exporter::ExportLevel += 1; Exporter::import(@_) }
+ }
+
+sub imported { $IMPORTED; }
+
+sub func1 { return "func1"; }
+
+sub func2 { return "func2"; }
+
+1;
diff --git a/cpan/Module-Load/t/to_load/ToBeLoaded b/cpan/Module-Load/t/to_load/ToBeLoaded
new file mode 100644
index 0000000000..6912615643
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/ToBeLoaded
@@ -0,0 +1 @@
+1; \ No newline at end of file
diff --git a/cpan/Module-Load/t/to_load/config_file b/cpan/Module-Load/t/to_load/config_file
new file mode 100644
index 0000000000..0c471319fe
--- /dev/null
+++ b/cpan/Module-Load/t/to_load/config_file
@@ -0,0 +1,30 @@
+ # Below is a sample of a config file you could use
+
+ # comments are denoted by a single '#'
+ # use a shared stack, or have a private instance?
+ # if none provided, set to '0',
+ private = 1
+
+ # do not be verbose
+ verbose = 0
+
+ # default tag to set on new items
+ # if none provided, set to 'NONE'
+ tag = SOME TAG
+
+ # default level to handle items
+ # if none provided, set to 'log'
+ level = carp
+
+ # extra files to include
+ # if none provided, no files are auto included
+ include = LoadMe.pl
+
+ # automatically delete items
+ # when you retrieve them from the stack?
+ # if none provided, set to '0'
+ remove = 1
+
+ # retrieve errors in chronological order, or not?
+ # if none provided, set to '1'
+ chrono = 0 \ No newline at end of file