Learning Perl Objects, References amp;amp; Modules [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Learning Perl Objects, References amp;amp; Modules [Electronic resources] - نسخه متنی

Randal L. Schwartz

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید














12.7 Setting the Path at the Right Time


The downside of
use being executed at compile time is that it also
looks at @INC at compile time, which can break
your program in hard-to-understand ways unless you take
@INC into consideration.

For example, suppose you have your own directory under
/home/gilligan/lib, and you place your own
Navigation::SeatOfPants module in
/home/gilligan/lib/Navigation/SeatOfPants.pm.
Simply saying:

use Navigation::SeatOfPants;

is unlikely to do anything useful because only the system directories
(and typically the current directory) are considered for
@INC. However, even adding:

push @INC, "/home/gilligan/lib";   # broken
use Navigation::SeatOfPants;

doesn't work. Why? Because the
push happens at runtime, long after the
use was attempted at compile time. One way to fix
this is to add a BEGIN block around the
push:

BEGIN { push @INC, "/home/gilligan/lib"; }
use Navigation::SeatOfPants;

Now the BEGIN block
compiles and executes at compile time, setting up the proper path for
the following use.

However, this is noisy and prone to require far more explanation than
you might be comfortable with, especially for the maintenance
programmer who has to edit your code later. Let's
replace all that clutter with a simple pragma:

use lib "/home/gilligan/lib";
use Navigation::SeatOfPants;

Here, the lib pragma
takes one or more arguments and adds them at the beginning of the
@INC array (think
"unshift").[11] It does so because it is processed at compile time, not
runtime. Hence, it's ready in time for the
use immediately following.

[11] use lib also unshifts an
architecture-dependent library below the requested library, making it
more valuable than the explicit counterpart presented earlier.


Because a use lib pragma will pretty much always
have a site-dependent pathname, it is traditional and encouraged to
put it near the top of the file. This makes it easier to find and
update when the file needs to move to a new system or when the
lib directory's name changes. (Of
course, you can eliminate use lib entirely if you
can install your modules in a standard @INC
locations, but that's not always practical.)

Think of use lib as not "use this
library," but rather "use this path
to find my libraries (and modules)." Too often, you
see code written like:

use lib "/home/gilligan/lib/Navigation/SeatOfPants.pm"; # WRONG

and then the programmer wonders why it didn't pull
in the definitions. Be aware that use
lib indeed runs at compile time, so this also
doesn't work:

my $LIB_DIR = "/home/gilligan/lib";
...
use lib $LIB_DIR; # BROKEN
use Navigation::SeatOfPants;

Certainly the
declaration of $LIB_DIR is established at compile
time (so you won't get an error with use
strict
, although the actual use lib
should complain), but the actual initialization to the
/home/gilligan/lib/ path happens at runtime. Oops,
too late again!

At
this point, you need to put something inside a
BEGIN block or perhaps rely on yet another
compile-time operation: setting a constant with use
constant
:

use constant LIB_DIR => "/home/gilligan/lib";
...
use lib LIB_DIR;
use Navigation::SeatOfPants;

There. Fixed again. That is,
until you need the library to depend on the result of a calculation.
(Where will it all end? Somebody stop the madness!) This should
handle about 99 percent of your needs.



/ 199