1Path::ScanINC(3)      User Contributed Perl Documentation     Path::ScanINC(3)
2
3
4

NAME

6       Path::ScanINC - Emulate Perls internal handling of @INC.
7

VERSION

9       version 1.000003
10

SYNOPSIS

12       The Aim of this module is to fully implement everything Perl does with
13       @INC, to be feature compatible with it, including the behavior with
14       regard to "sub refs" in @INC.
15
16               use Path::ScanINC;
17
18               # Normal usage.
19               my $inc = Path::ScanINC->new( );
20
21               # In case you need something that isn't @INC
22               # but works like it
23
24               my $inc = Path::ScanINC->new( inc => \@INC );
25
26               # Freeze the value of @INC at the time of object instantiation
27               # with regard to behaviour so later changes to @INC have no effect
28
29               my $inc = Path::ScanINC->new( immutable => 1 );
30
31               # Return the first file in @INC that matches.
32
33               my $file = $inc->first_file('Path', 'ScanINC.pm' );
34
35               # Find all possible versions of modules in @INC
36               my ( @files ) = $inc->all_files('Path', 'ScanINC.pm');
37
38               # Try to discover a File::ShareDir 'module' root.
39               my $dir = $inc->first_dir('auto','share','module');
40
41               # Should return the same as File::ShareDir::module_dir('Path::ScanINC')
42               # ( assuming such a directory existed, which there is presently no plans of )
43               my $dir = $inc->first_dir('auto','share','module','Path-ScanINC');
44
45
46               # Find All File::ShareDir roots in @INC
47               my ( @dirs ) = $inc->all_dirs('auto', 'share');
48

DESCRIPTION

50       "Path::ScanINC" is a basic tool for traversing @INC in a "perl"-like
51       manner, stepping over some common pitfalls with using it. It also has
52       the property of being able to capture @INC states to emulate a portable
53       isolated library resolver.
54

REF SUPPORT IN @INC

56       This module has elemental support for discovery of results in @INC
57       using "CODE"/"ARRAY"/"BLESSED" entries in @INC. However, due to a
58       limitation as to how "perl" itself implements this functionality, the
59       best we can do at present is simply return what the above are expected
60       to return. This means if you have any of the above ref-types in @INC,
61       and one of those returns "a true value", you'll get handed back an
62       "ARRAY" reference instead of the file you were expecting.
63
64       Fortunately, @INC barely ever has refs in it. But in the event you need
65       to work with refs in @INC and you expect that those refs will return
66       "true", you have to pick one of two options, either :
67
68       a. Write your code to work with the "array-ref" returned by the
69       respective reference on a match
70       b. Use the "all_" family of methods and try pretending that there are
71       no "array-refs" in the list it returns.
72
73       Its possible in a future release we may have better choices how to
74       handle this situation in future, but don't bet on it.
75
76       Given that the API as defined by Perl mandates "code-ref"'s return
77       lists containing "file-handles" or iterative "code-ref"'s , not actual
78       files, the best I can foresee at this time we'd be able to do to make
79       life easier for you is creating a fake library somewhere in a "tempdir"
80       and stuffing the result of the "code-ref"'s into files in that
81       directory prior to returning a path to the generated file.
82
83       ( And it also tells me that they have to be "Real" file handles, not
84       tied or blessed ones, so being able to ask a "filehandle" what file it
85       represents is equally slim.... if that is of course what you require )
86
87       For more details, see "perldoc perlfunc" or "perldoc -f require" .
88

METHODS

90   new
91               my $object = $class->new(
92                        inc => [ 'x', 'y', 'z' , ],
93                        immutable => 1 | undef
94               );
95
96   immutable
97               if( $inc->immutable ) {
98                       print "We're working with a snapshotted version of @INC";
99               }
100
101   inc
102               for my $i ( $inc->inc ) {
103                       say "Plain: $incer" if not ref $incer;
104                       say "Callback: $incer" if ref $incer;
105               }
106
107       Returns a copy of the internal version of @INC it will be using.
108
109       If the object is "immutable", then this method will continue to report
110       the same value as c<@INC>, or will be updated every time the original
111       array reference passed during construction gets updated:
112
113               my $ref = [];
114               my $a = Path::ScanINC->new( inc => $ref );
115               my $b = Path::ScanINC->new( inc => $ref, immutable => 1 );
116
117               push @{$ref} , 'a';
118
119               is( [ $a->inc ]->[0] , 'a' , "non-immutable references keep tracking their original" );
120               isnt( [ $b->inc ]->[0] , 'a' , "immutable references are shallow-copied at construction" );
121
122       Do note of course that is a SHALLOW copy, so if you have multiple @INC
123       copies sharing the same "array"/"bless" references, changes to those
124       references will be shared amongst all @INC's .
125
126   first_file
127               if( defined ( my $file = $inc->first_file('Moose.pm') ) {
128                       print "Yep, Moose seems to be available in \@INC , its at $file, but its not loaded (yet)\n";
129               }
130
131       This proves to be a handy little gem that replaces the oft used
132
133               if( try { require Moose ; 1 } ){
134                       Yadayadayada
135               }
136
137       And adds the benefit of not needing to actually source the file to see
138       if it exists or not.
139
140       IMPORTANT: PORTABILITIY
141
142       For best system portability, where possible, its suggested you specify
143       paths as arrays of strings, not slash-separated strings.
144
145               $inc->first_file('MooseX' , 'Declare.pm')  # Good
146               $inc->first_file('MooseX/Declare.pm')      # Bad.
147
148       This is for several reasons, all of which can be summarized as
149       "Windows".
150
151       ·   %INC keys all use Unix notation.
152
153       ·   @INC callbacks expect Unix notation.
154
155       ·   "\" is a valid path part on Unix.
156
157       ·   On Win32, we have to use "\" Separation, not "/" for resolving
158           physical files.
159
160       The sum of these means if you do this:
161
162               $inc->first_file('MooseX/Declare.pm')
163
164       On win32, it might just end up doing:
165
166               C:\some\path\here/MooseX/Declare.pm
167
168       Which may or may not work.
169
170       And additionally, if the above module is loaded, it will be loaded as
171
172               "MooseX/Declare.pm"
173
174       in %INC, not what you'd expect, "MooseX\Declare.pm"
175
176   all_files
177       Returns all matches in all @INC paths.
178
179               my $inc = Path::ScanINC->new();
180               push @INC, 'lib';
181               my ( @files ) = $inc->all_files('Something','Im','Working','On.pm');
182               pp(\@files );
183
184               # [
185               #    '/something/........./lib/Something/Im/Working/On.pm',
186               #    '/something/....../share/per5/lib/site_perl/5.15.9/Something/Im/Working/On.pm',
187               # ]
188
189       Chances are if you understand how this can be useful, you'll do so
190       immediately.
191
192       Useful for debugging what module is being loaded, and possibly
193       introspecting information about multiple parallel installs of modules
194       in %ENV, such as frequently the case with 'dual-life' modules.
195
196               perl -MPath::ScanINC -E 'my $scanner = Path::ScanINC->new(); say for $scanner->all_files(qw( Scalar Util.pm ))'
197               /usr/lib64/perl5/vendor_perl/5.12.4/x86_64-linux/Scalar/Util.pm
198               /usr/lib64/perl5/5.12.4/x86_64-linux/Scalar/Util.pm
199
200       Sort-of like ye' olde' "perldoc -l", but more like "man -a"
201
202       I might even be tempted to make a sub-module to make one-liners easier
203       like
204
205               perl -MPath::ScanINC::All=Scalar/Util.pm
206
207       REMINDER: If there are "REFS" in @INC that match, they'll return
208       "array-ref"'s, not strings.
209
210   first_dir
211       Just like "first_file" except for locating directories.
212
213   all_dirs
214       Just like "all_dirs" except for locating directories.
215

AUTHOR

217       Kent Fredric <kentnl@cpan.org>
218
220       This software is copyright (c) 2017 by Kent Fredric <kentnl@cpan.org>.
221
222       This is free software; you can redistribute it and/or modify it under
223       the same terms as the Perl 5 programming language system itself.
224
225
226
227perl v5.30.0                      2019-07-26                  Path::ScanINC(3)
Impressum