File Coverage

blib/lib/Paranoid/Module.pm
Criterion Covered Total %
statement 53 56 94.6
branch 16 20 80.0
condition n/a
subroutine 10 10 100.0
pod 1 1 100.0
total 80 87 91.9


line stmt bran cond sub pod time code
1             # Paranoid::Module -- Paranoid Module Loading Routines
2             #
3             # $Id: lib/Paranoid/Module.pm, 2.08 2020/12/31 12:10:06 acorliss Exp $
4             #
5             # This software is free software. Similar to Perl, you can redistribute it
6             # and/or modify it under the terms of either:
7             #
8             # a) the GNU General Public License
9             # as published by the
10             # Free Software Foundation ; either version 1
11             # , or any later version
12             # , or
13             # b) the Artistic License 2.0
14             # ,
15             #
16             # subject to the following additional term: No trademark rights to
17             # "Paranoid" have been or are conveyed under any of the above licenses.
18             # However, "Paranoid" may be used fairly to describe this unmodified
19             # software, in good faith, but not as a trademark.
20             #
21             # (c) 2005 - 2020, Arthur Corliss (corliss@digitalmages.com)
22             # (tm) 2008 - 2020, Paranoid Inc. (www.paranoid.com)
23             #
24             #####################################################################
25              
26             #####################################################################
27             #
28             # Environment definitions
29             #
30             #####################################################################
31              
32             package Paranoid::Module;
33              
34 12     12   1302 use 5.008;
  12         42  
35              
36 12     12   99 use strict;
  12         101  
  12         355  
37 12     12   67 use warnings;
  12         18  
  12         449  
38 12     12   86 use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
  12         22  
  12         717  
39 12     12   64 use base qw(Exporter);
  12         23  
  12         1043  
40 12     12   82 use Paranoid;
  12         23  
  12         586  
41 12     12   556 use Paranoid::Debug qw(:all);
  12         25  
  12         1999  
42 12     12   5182 use Paranoid::Input;
  12         28  
  12         735  
43 12     12   86 use Carp;
  12         24  
  12         5707  
44              
45             ($VERSION) = ( q$Revision: 2.08 $ =~ /(\d+(?:\.\d+)+)/sm );
46              
47             @EXPORT = qw(loadModule);
48             @EXPORT_OK = @EXPORT;
49             %EXPORT_TAGS = ( all => [@EXPORT_OK], );
50              
51             #####################################################################
52             #
53             # Module code follows
54             #
55             #####################################################################
56              
57             {
58             my %modules; # List of modules compiled
59             # {modules} => boolean
60             my %imports; # List of modules/tagsets imported from callers
61             # {module*tagset*caller} => boolean
62              
63             sub loadModule {
64              
65             # Purpose: Attempts to load a module via an eval. Caches the
66             # result
67             # Returns: True (1) if the module was successfully loaded,
68             # False (0) if there are any errors
69             # Usage: $rv = loadModule($moduleName);
70              
71 21     21 1 103 my $module = shift;
72 21         94 my @args = @_;
73 21         40 my $rv = 0;
74 21         50 my $caller = scalar caller;
75 21 100       102 my $a = @args ? 'qw(' . ( join ' ', @args ) . ')' : '';
76 21         65 my ( $m, $cm );
77              
78 21 50       68 croak 'Mandatory first argument must be a defined module name'
79             unless defined $module;
80              
81 21         73 pdebug( 'entering w/(%s)(%s)', PDLEVEL1, $module, @args );
82 21         70 pIn();
83              
84             # Check to see if module has been loaded already
85 21 100       102 unless ( exists $modules{$module} ) {
86              
87             # First attempt at loading this module, so
88             # detaint and require
89 20 50       112 if ( detaint( $module, 'filename', $m ) ) {
90 20         53 $module = $m;
91             } else {
92 0         0 Paranoid::ERROR =
93             pdebug( 'failed to detaint module name (%s)',
94             PDLEVEL1, $module );
95 0         0 $modules{$module} = 0;
96             }
97              
98             # Skip if the detainting failed
99 20 50       58 unless ( exists $modules{$module} ) {
100              
101             # Try to load it
102 20 100       1623 $modules{$module} = eval "require $module; 1;" ? 1 : 0;
103             pdebug( 'attempted load of %s: %s',
104 20         130 PDLEVEL2, $module, $modules{$module} );
105              
106             }
107             }
108              
109             # Define the module/tagset/caller
110 21 100       66 if (@args) {
111 19 100       70 $a = '()' if $a eq 'qw()';
112             } else {
113 2         5 $a = '';
114             }
115 21         71 $cm = "$module*$a*$caller";
116              
117             # Check to see if this caller has imported these symbols
118             # before
119 21 100       73 if ( $modules{$module} ) {
120 18 50       54 if ( exists $imports{$cm} ) {
121              
122 0         0 pdebug( 'previous attempt to import to %s',
123             PDLEVEL2, $caller );
124              
125             } else {
126              
127 18         103 pdebug( 'importing symbols into %s', PDLEVEL2, $caller );
128 18         1369 $imports{$cm} = eval << "EOF";
129             {
130             package $caller;
131             import $module $a;
132             1;
133             }
134             EOF
135              
136             }
137              
138 18         134 $rv = $imports{$cm};
139             }
140              
141 21         107 pOut();
142 21         82 pdebug( 'leaving w/rv: %s', PDLEVEL1, $modules{$module} );
143              
144             # Return result
145 21         469 return $modules{$module};
146             }
147             }
148              
149             1;
150              
151             __END__