Trình thông dịch Perl (chạy chương trình perl của bạn) sẽ sử dụng một mảng đặc biệt gọi là @INC
để tìm kiếm tệp chứa mô-đun.
Mỗi giá trị trong mảng @INC
là tên thư mục (nhưng xem ghi chú bên dưới); Perl sẽ tìm kiếm trong các thư mục đó trong vòng lặp bằng cách sử dụng các quy tắc được chỉ định bên dưới. (Vui lòng tham khảo this SO post for details of how the contents of @INC are determined).
Nếu không tìm thấy tệp của mô-đun sau khi hết @INC
, quá trình biên dịch của chương trình sẽ bị hủy bỏ do lỗi. Nếu tìm thấy tệp của mô-đun trong một trong các thư mục được chỉ định trong @INC
, tìm kiếm được hoàn tất mà không cần xem phần còn lại của @INC
.
Cách Perl tìm kiếm một tập tin mô-đun trong mỗi thư mục được liệt kê trong @INC
là như sau:
Đầu tiên, nó sẽ tách thành phần thứ bậc tên mô-đun của (từ cách nhau bởi ::
), vào thành phần cuối cùng - sẽ được sử dụng để tạo thành tên tệp - và đường dẫn phân cấp (tất cả các thành phần nằm trước ::
cuối cùng).
Trong trường hợp tên mô-đun chỉ có một thành phần (không có ::
, ví dụ: MyModule1
ở trên), đường dẫn phân cấp trống và tên tệp là tên của mô-đun. Trong ví dụ thứ hai trong câu hỏi này, thành phần cuối cùng là MyModule2
và đường dẫn phân cấp sẽ là This::Here
.
Tên tệp dự kiến sẽ được xác định bằng cách nối thành phần cuối cùng của tên mô-đun với tiện ích mở rộng .pm
. Ví dụ. MyModule1.pm
và MyModule2.pm
trong các ví dụ của chúng tôi.
LƯU Ý: Tên mô-đun rõ ràng là phân biệt chữ hoa chữ thường trên Unix và các hệ điều hành khác nơi đặt tên tệp/thư mục phân biệt chữ hoa chữ thường.
thư mục của module sẽ được xác định bởi:
Lấy danh mục kế tiếp từ @INC
- giả sử /usr/lib/perl
làm ví dụ
Hình thành một thư mục con của thư mục đó bằng cách tham gia hệ thống phân cấp đường dẫn của tên mô-đun (nếu có) và thay thế "::" bằng /
hoặc bất kỳ ký tự nào mà hệ điều hành sử dụng làm dấu tách thư mục. Trong hai ví dụ của chúng tôi, mô-đun đầu tiên sẽ được tìm kiếm trong /usr/lib/perl
(không có thư mục con) và mô-đun thứ hai trong /usr/lib/perl/This/Here
.
LƯU Ý: ở trên là một việc đơn giản hóa nhẹ - @INC
may also contain subroutine references and object references, mà nạp mô-đun như mã tùy chỉnh của họ quy định cụ thể thay vì thực hiện việc tra cứu trong danh bạ theo quy định tại # 2 logic ở trên. Chức năng đó dường như rất hiếm khi được sử dụng và bài viết này giả định rằng toàn bộ @INC
chỉ chứa các thư mục.
Hãy cùng điểm qua một ví dụ cụ thể, giả định rằng @INC
của bạn có chứa hai thư mục con: ("/usr/lib/perl", "/opt/custom/lib")
.
Sau đó Perl sẽ tìm kiếm như sau:
==========================================================================
| Module | Try # | File to try
==========================================================================
| MyModule1 | Try 1 | /usr/lib/perl/MyModule1.pm
| MyModule1 | Try 2 | /opt/custom/lib/MyModule1.pm
==========================================================================
| This::Here::MyModule2 | Try 1 | /usr/lib/perl/This/Here/MyModule2.pm
| This::Here::MyModule2 | Try 2 | /opt/custom/lib/This/Here/MyModule2.pm
==========================================================================
Hãy nhớ rằng Perl dịch viên sẽ ngừng cố gắng để tìm kiếm một lần nó tìm thấy các tập tin trong một trong những địa điểm mà không cần cố gắng để xem nếu tập tin là tại các địa điểm sau cũng. Ví dụ. nếu có /usr/lib/perl/This/Here/MyModule2.pm
, thì Perl sẽ không tìm kiếm và cũng không quan tâm đến sự tồn tại của /opt/custom/lib/This/Here/MyModule2.pm
.
LƯU Ý: @INC được sử dụng bất cứ khi nào thông dịch viên Perl đang sử dụng require
cơ chế giống như để nhập mô-đun Perl. Điều này bao gồm:
require
thị bản thân
use MyModule
statement (tương đương với yêu cầu + nhập khẩu)
use base
(tương đương với yêu cầu + "đẩy @ISA")
Tôi không thể tìm thấy câu trả lời toàn diện cho câu hỏi này trên SO mà tôi có thể liên kết đến, vì vậy tôi quyết định tạo một câu hỏi. Nếu câu trả lời được cung cấp dưới đây là cần bổ sung/sửa chữa, xin vui lòng có nó :) – DVK