File Coverage

blib/lib/Paranoid/Module.pm
Criterion Covered Total %
statement 51 54 94.4
branch 16 20 80.0
condition n/a
subroutine 10 10 100.0
pod 1 1 100.0
total 78 85 91.7


line stmt bran cond sub pod time code
1             # Paranoid::Module -- Paranoid Module Loading Routines
2             #
3             # $Id: lib/Paranoid/Module.pm, 2.10 2022/03/08 00:01:04 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 29     29   6655 use 5.008;
  29         99  
35              
36 29     29   129 use strict;
  29         49  
  29         470  
37 29     29   124 use warnings;
  29         50  
  29         789  
38 29     29   227 use vars qw($VERSION @EXPORT @EXPORT_OK %EXPORT_TAGS);
  29         68  
  29         1752  
39 29     29   172 use base qw(Exporter);
  29         45  
  29         1833  
40 29     29   164 use Paranoid;
  29         99  
  29         1433  
41 29     29   538 use Paranoid::Debug qw(:all);
  29         45  
  29         3811  
42 29     29   6408 use Paranoid::Input;
  29         51  
  29         1434  
43 29     29   160 use Carp;
  29         45  
  29         11752  
44              
45             ($VERSION) = ( q$Revision: 2.10 $ =~ /(\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 44     44 1 128 my $module = shift;
72 44         132 my @args = @_;
73 44         89 my $rv = 0;
74 44         87 my $caller = scalar caller;
75 44 100       252 my $a = @args ? 'qw(' . ( join ' ', @args ) . ')' : '';
76 44         102 my ( $m, $cm );
77              
78 44 50       132 croak 'Mandatory first argument must be a defined module name'
79             unless defined $module;
80              
81 44         240 subPreamble( PDLEVEL1, '$;@', $module, @args );
82              
83             # Check to see if module has been loaded already
84 44 100       169 unless ( exists $modules{$module} ) {
85              
86             # First attempt at loading this module, so
87             # detaint and require
88 43 50       196 if ( detaint( $module, 'filename', $m ) ) {
89 43         103 $module = $m;
90             } else {
91 0         0 Paranoid::ERROR =
92             pdebug( 'failed to detaint module name (%s)',
93             PDLEVEL1, $module );
94 0         0 $modules{$module} = 0;
95             }
96              
97             # Skip if the detainting failed
98 43 50       159 unless ( exists $modules{$module} ) {
99              
100             # Try to load it
101 43 100       3114 $modules{$module} = eval "require $module; 1;" ? 1 : 0;
102             pdebug( 'attempted load of %s: %s',
103 43         275 PDLEVEL2, $module, $modules{$module} );
104              
105             }
106             }
107              
108             # Define the module/tagset/caller
109 44 100       141 if (@args) {
110 42 100       153 $a = '()' if $a eq 'qw()';
111             } else {
112 2         4 $a = '';
113             }
114 44         154 $cm = "$module*$a*$caller";
115              
116             # Check to see if this caller has imported these symbols
117             # before
118 44 100       127 if ( $modules{$module} ) {
119 41 50       137 if ( exists $imports{$cm} ) {
120              
121 0         0 pdebug( 'previous attempt to import to %s',
122             PDLEVEL2, $caller );
123              
124             } else {
125              
126 41         131 pdebug( 'importing symbols into %s', PDLEVEL2, $caller );
127 41         2373 $imports{$cm} = eval << "EOF";
128             {
129             package $caller;
130             import $module $a;
131             1;
132             }
133             EOF
134              
135             }
136              
137 41         154 $rv = $imports{$cm};
138             }
139              
140 44         2339 subPostamble( PDLEVEL1, '$', $modules{$module} );
141              
142             # Return result
143 44         702 return $modules{$module};
144             }
145             }
146              
147             1;
148              
149             __END__