Chúng tôi sẽ xem xét cách các nội dung của mảng này được xây dựng và có thể được thao tác để ảnh hưởng đến nơi trình thông dịch Perl sẽ tìm thấy các tệp mô-đun.
Mặc định @INC
Trình thông dịch Perl được biên dịch với một @INC
giá trị mặc định cụ thể . Để tìm ra giá trị này, hãy chạy env -i perl -V
lệnh ( env -i
bỏ qua PERL5LIB
biến môi trường - xem # 2) và trong đầu ra, bạn sẽ thấy một cái gì đó như thế này:
$ env -i perl -V
...
@INC:
/usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/site_perl/5.18.0
/usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/5.18.0
.
Lưu ý .
ở cuối; đây là thư mục hiện tại (không nhất thiết phải giống với thư mục của tập lệnh). Nó bị thiếu trong Perl 5.26+ và khi Perl chạy với -T
(bật kiểm tra mờ ) .
Để thay đổi đường dẫn mặc định khi định cấu hình biên dịch nhị phân Perl, hãy đặt tùy chọn cấu hình otherlibdirs
:
Configure -Dotherlibdirs=/usr/lib/perl5/site_perl/5.16.3
Biến môi trường PERL5LIB
(hoặc PERLLIB
)
Perl trả trước @INC
với một danh sách các thư mục (được phân tách bằng dấu hai chấm) có trong PERL5LIB
(nếu nó không được xác định, PERLLIB
được sử dụng) biến môi trường của trình bao của bạn. Để xem nội dung của các biến @INC
sau PERL5LIB
và PERLLIB
môi trường đã có hiệu lực, hãy chạy perl -V
.
$ perl -V
...
%ENV:
PERL5LIB="/home/myuser/test"
@INC:
/home/myuser/test
/usr/lib/perl5/site_perl/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/site_perl/5.18.0
/usr/lib/perl5/5.18.0/x86_64-linux-thread-multi-ld
/usr/lib/perl5/5.18.0
.
-I
tùy chọn dòng lệnh
Perl trả trước @INC
với một danh sách các thư mục (được phân tách bằng dấu hai chấm) được truyền dưới dạng giá trị của -I
tùy chọn dòng lệnh. Điều này có thể được thực hiện theo ba cách, như thường lệ với các tùy chọn Perl:
Vượt qua nó trên dòng lệnh:
perl -I /my/moduledir your_script.pl
Truyền nó qua dòng đầu tiên (shebang) của tập lệnh Perl của bạn:
#!/usr/local/bin/perl -w -I /my/moduledir
Vượt qua nó như một phần của PERL5OPT
(hoặc PERLOPT
) biến môi trường (xem chương 19.02 trong Lập trình Perl )
Vượt qua nó thông qua lib
pragma
Perl trả trước @INC
với một danh sách các thư mục được truyền vào nó thông qua use lib
.
Trong một chương trình:
use lib ("/dir1", "/dir2");
Trên dòng lệnh:
perl -Mlib=/dir1,/dir2
Bạn cũng có thể loại bỏ các thư mục từ @INC
thông quano lib
.
Bạn có thể thao tác trực tiếp @INC
như một mảng Perl thông thường.
Lưu ý: Vì @INC
được sử dụng trong giai đoạn biên dịch, điều này phải được thực hiện bên trong một BEGIN {}
khối, trước use MyModule
câu lệnh.
Thêm thư mục vào đầu thông qua unshift @INC, $dir
.
Thêm thư mục vào cuối thông qua push @INC, $dir
.
Làm bất cứ điều gì khác bạn có thể làm với một mảng Perl.
Lưu ý: Các thư mục được unshifted lên @INC
theo thứ tự được liệt kê trong câu trả lời này, ví dụ như mặc định @INC
là cuối cùng trong danh sách, trước bởi PERL5LIB
, trước bởi -I
, trước bằng use lib
và trực tiếp @INC
thao tác, sau này hai trộn lẫn trong bất cứ đặt họ trong mã Perl.
Người giới thiệu:
Dường như không có @INC
bài đăng loại FAQ toàn diện trên Stack Overflow, vì vậy câu hỏi này được dự định là một.
Khi nào nên sử dụng từng phương pháp?
Nếu các mô-đun trong một thư mục cần được sử dụng bởi nhiều / tất cả các tập lệnh trên trang web của bạn, đặc biệt được điều hành bởi nhiều người dùng, thư mục đó sẽ được đưa vào mặc định @INC
được biên dịch thành nhị phân Perl.
Nếu các mô-đun trong thư mục sẽ được sử dụng riêng bởi một người dùng cụ thể cho tất cả các tập lệnh mà người dùng chạy (hoặc nếu biên dịch lại Perl không phải là một tùy chọn để thay đổi mặc định @INC
trong trường hợp sử dụng trước đó) PERL5LIB
, thường là trong quá trình đăng nhập của người dùng.
Lưu ý: Xin lưu ý các cạm bẫy biến môi trường Unix thông thường - ví dụ: trong một số trường hợp nhất định chạy tập lệnh vì người dùng cụ thể không đảm bảo chạy chúng với môi trường của người dùng đó được thiết lập, ví dụ như thông qua su
.
Nếu các mô-đun trong thư mục chỉ cần được sử dụng trong các trường hợp cụ thể (ví dụ: khi tập lệnh được thực thi ở chế độ phát triển / gỡ lỗi, bạn có thể đặt PERL5LIB
thủ công hoặc chuyển -I
tùy chọn sang perl.
Nếu các mô-đun chỉ cần được sử dụng cho các tập lệnh cụ thể, bởi tất cả người dùng sử dụng chúng, hãy sử dụng use lib
/ no lib
pragmas trong chính chương trình. Nó cũng nên được sử dụng khi thư mục cần tìm kiếm cần được xác định động trong thời gian chạy - ví dụ: từ các tham số dòng lệnh hoặc đường dẫn của tập lệnh (xem mô-đun FindBin để biết trường hợp sử dụng rất hay).
Nếu các thư mục @INC
cần được thao tác theo một số logic phức tạp, không thể quá khó sử dụng bằng cách kết hợp use lib
/ no lib
pragmas, thì hãy sử dụng @INC
thao tác trực tiếp bên trong BEGIN {}
khối hoặc bên trong thư viện mục đích đặc biệt được chỉ định để @INC
thao tác, phải được sử dụng bởi tập lệnh của bạn (s) trước khi bất kỳ mô-đun khác được sử dụng.
Một ví dụ về điều này là tự động chuyển đổi giữa các thư viện trong các thư mục prod / uat / dev, với việc lấy thư viện thác nước trong prod nếu nó bị thiếu từ dev và / hoặc UAT (điều kiện cuối cùng làm cho giải pháp "sử dụng lib + FindBin" tiêu chuẩn khá phức tạp. minh họa chi tiết cho kịch bản này là trong Làm cách nào để sử dụng các mô-đun Perl beta từ các tập lệnh beta Perl ? .
Một trường hợp sử dụng bổ sung để thao tác trực tiếp @INC
là có thể thêm các tham chiếu chương trình con hoặc tham chiếu đối tượng (vâng, Virginia, @INC
có thể chứa mã Perl tùy chỉnh và không chỉ tên thư mục, như được giải thích trong Khi nào là tham chiếu chương trình con trong @INC được gọi? ).