1FindLib(3)            User Contributed Perl Documentation           FindLib(3)
2
3
4

NAME

6       File::FindLib - Find and use a file/dir from a directory above your
7       script file
8

SYNOPSIS

10           use File::FindLib 'lib';
11
12       Or
13
14           use File::FindLib 'lib/MyCorp/Setup.pm';
15

DESCRIPTION

17       File::FindLib starts in the directory where your script (or library) is
18       located and looks for the file or directory whose name you pass in.  If
19       it isn't found, then FindLib looks in the parent directory and
20       continues moving up parent directories until it finds it or until there
21       is not another parent directory.
22
23       If it finds the named path and it is a directory, then it prepends it
24       to @INC.  That is,
25
26           use File::FindLib 'lib';
27
28       is roughly equivalent to:
29
30           use File::Basename qw< dirname >;
31           use lib dirname(__FILE__) . '/../../../lib';
32
33       except you don't have to know how many '../'s to include and it adjusts
34       if __FILE__ is a symbolic link.
35
36       If it finds the named path and it is a file, then it loads the Perl
37       code stored in that file.  That is,
38
39           use File::FindLib 'lib/MyCorp/Setup.pm';
40
41       is roughly equivalent to:
42
43           use File::Basename qw< dirname >;
44           BEGIN {
45               require dirname(__FILE__) . '/../../../lib/MyCorp/Setup.pm';
46           }
47
48       except you don't have to know how many '../'s to include (and it
49       adjusts if __FILE__ is a symbolic link).
50
51   MOTIVATION
52       It is common to have a software product that gets deployed as a tree of
53       directories containing commands (scripts) and/or test scripts in the
54       deployment that need to find Perl libraries that are part of the
55       deployment.
56
57       By including File::FindLib in your standard Perl deployment, you can
58       include one or more custom initialization or boot-strap modules in each
59       of your software deployments and easily load one by pasting one short
60       line into each script.  The custom module would likely add some
61       directories to @INC so that the script can then just load any modules
62       that were included in the deployment.
63
64       For example, you might have a deployment structure that looks like:
65
66           bin/init
67           ...
68           db/bin/dump
69           ...
70           lib/MyCorp/Setup.pm
71           lib/MyCorp/Widget.pm
72           lib/MyCorp/Widget/Connect.pm
73           ...
74           t/TestEnv.pm
75           t/itPing.t
76           t/itTimeOut.t
77           t/MyCorp/Widget/basic.t
78           ...
79           t/MyCorp/Widget/Connect/retry.t
80           ...
81           t/testlib/MyTest.pm
82           ...
83
84       And your various Perl scripts like bin/init and db/bin/dump might start
85       with:
86
87           use File::FindLib 'lib/MyCorp/Setup.pm';
88           use MyCorp::Widget;
89
90       And Setup.pm might start with:
91
92           package MyCorp::Setup;
93           use File::FindLib 'lib';
94
95       While your various test scripts might start with:
96
97           use File::FindLib 't/TestEnv.pm';
98           use MyTest qw< plan ok >;
99
100       where TestEnv.pm might start with:
101
102           package TestEnv;
103           use File::FindLib 'testlib';    # Find modules in $repo/t/testlib/
104           use File::FindLib 'lib';        # Find modules in $repo/lib/
105
106       And you don't have to worry about having to update a script if it gets
107       moved to a different point in the deployment directory tree.
108
109   SYMBOLIC LINKS
110       If the calling script/library was loaded via a symbolic link (if "-l
111       __FILE__" is true inside the calling code), then File::FindLib will
112       start looking from where that symbolic link points.  If it points at
113       another symbolic link or if any of the parent directories are symbolic
114       links, then File::FindLib will ignore this fact.
115
116       So, if we have the following symbolic links:
117
118           /etc/init.d/widget -> /site/mycorp/widget/bin/init-main
119           /site/mycorp/widget/bin/init-main -> ../util/admin/init
120           /site/mycorp/widget/ -> ../dist/widget/current/
121           /site/mycorp/dist/widget/current/ -> 2011-12-01/
122           /site/mycorp/dist/widget/2011-12-01 -> v1.042_037/
123           /site/mycorp/ -> /export/site/mycorp/
124           /site -> /export/var/site
125
126       And the following command produces the following output:
127
128           $ head -2 /etc/init.d/widget
129           #!/usr/bin/perl
130           use File::FindLib 'lib/Setup.pm';
131           $
132
133       Then File::FindLib will do:
134
135           See that it was called from /etc/init.d/widget.
136           See that this is a symbolic link.
137           Act like it was called from /site/mycorp/widget/bin/init-main.
138           (Ignore that this is another symbolic link.)
139           Search for:
140               /site/mycorp/widget/bin/lib/Setup.pm
141               /site/mycorp/widget/lib/Setup.pm
142               /site/mycorp/lib/Setup.pm
143               /site/lib/Setup.pm
144               /lib/Setup.pm
145
146       Only the first symbolic link that we mentioned is noticed.
147
148       This would be unfortunate if you also have the symbolic link:
149
150           /etc/rc2.d/S99widget -> ../init.d/widget
151
152       Since running that command would cause the following searches:
153
154           /etc/init.d/lib/Setup.pm
155           /etc/lib/Setup.pm
156           /lib/Setup.pm
157
158       If you instead made a hard link:
159
160           # ln /etc/init.d/widget /etc/rc2.d/S99widget
161
162       then /etc/init.d/widget would also be a symbolic link to
163       /site/mycorp/widget/bin/init-main which would surely work better.
164
165       So future versions of File::FindLib may notice more cases of symbolic
166       links or provide options for controlling which symbolic links to
167       notice.
168
169   %INC
170       The code:
171
172           use File::FindLib 'lib/MyCorp/Setup.pm';
173
174       is more accurately approximated as:
175
176           use File::Basename qw< dirname >;
177           BEGIN {
178               my $path= dirname(__FILE__) . '/../../../lib/MyCorp/Setup.pm';
179               require $path;
180               $INC{'MyCorp/Setup.pm'} ||= $INC{$path};
181           }
182
183       The setting of $INC{'MyCorp/Setup.pm'} is so that:
184
185           use File::FindLib 'lib/MyCorp/Setup.pm';
186           ...
187           use MyCorp::Setup;
188
189       doesn't try to load the MyCorp::Setup module twice.
190
191       Though, this is only done if lib/MyCorp/Setup.pm defines a
192       MyCorp::Setup package... and $INC{'MyCorp/Setup.pm'} isn't already set
193       and there is no lib::MyCorp::Setup package defined.  See the source
194       code if you have to know every detail of the heuristics used, though
195       misfires are unlikely (especially since module names are usually
196       capitalized while library subdirectory names usually are not).
197
198       Even this problem case is unlikely and the consequences of loading the
199       same module twice are often just harmless warnings, if that.
200
201       So this detail will not matter most of the time.
202

PLANS

204       I'd like to support a more powerful interface.  For example:
205
206           use File::FindLib(
207               -from           => __FILE__,
208               -upto           => 'ReleaseVersion.txt',
209               -inc            => 'custom/lib',    # Like: use lib ...
210               +inc            => 'lib',           # Like: push @INC, ...
211               -load           => 'initEnv.pl',    # Like: require ...
212               \my $DataDir    => 'custom/data',   # Sets $DataDir to full path
213           );
214
215       But adding such an interface should not interfere with the one-argument
216       interface already implemented.
217

CONTRIBUTORS

219       Author: Tye McQueen, http://perlmonks.org/?node=tye
220

ALSO SEE

222       Lake Missoula
223
224
225
226perl v5.30.1                      2020-01-30                        FindLib(3)
Impressum