2013-07-28 26 views
21

Tôi không thể hiểu trường hợp khác biệt/sử dụng của EXPORT_OK so với EXPORT là gì.
Hầu hết các nguồn lực đề cập đến điều gì đó trong dòng:xuất khẩu vs export_ok trong perl

@Export cho phép xuất khẩu các chức năng và các biến của mô-đun để namespace của người dùng bằng cách sử dụng phương pháp nhập khẩu tiêu chuẩn. Bằng cách này, chúng tôi không cần phải tạo các đối tượng cho các mô-đun để truy cập các thành viên của nó.
@EXPORT_OK thực hiện xuất biểu tượng theo yêu cầu cho danh sách có chọn lọc các ký hiệu (chương trình con và biến) của mô-đun.

Nhưng tôi thực sự không thấy sự khác biệt/ý nghĩa ở đây.
Có thể ai đó vui lòng cung cấp một ví dụ cơ bản nhỏ về sự khác biệt/cách sử dụng của 2 biểu tượng này không?

+0

Bạn không nên xuất nhiều biểu tượng theo mặc định nếu có. @EXPORT thường sẽ nhỏ hoặc trống. @EXPORT_OK có thể bao gồm nhiều hơn nữa. Ví dụ: Mã hóa xuất 'mã hóa' và' giải mã' theo mặc định ('@ EXPORT'), nhưng không phải' is_utf8' ('@ EXPORT_OK') – ikegami

Trả lời

15

Từ fine Exporter manual:

  • use YourModule;
    này nhập khẩu tất cả các biểu tượng từ YourModule của @EXPORT vào không gian tên của sử dụng tuyên bố.
  • use YourModule();
    Điều này làm cho perl tải mô-đun của bạn nhưng không nhập bất kỳ ký hiệu nào.
  • use YourModule qw(...);
    Điều này chỉ nhập các ký hiệu được liệt kê bởi người gọi vào không gian tên của chúng. Tất cả các biểu tượng được liệt kê phải nằm trong số @EXPORT hoặc @EXPORT_OK của bạn, nếu không có lỗi xảy ra. Các tính năng xuất khẩu nâng cao của Nhà xuất khẩu được truy cập như thế này, nhưng với các mục danh sách khác biệt về mặt cú pháp với các tên biểu tượng.

Vì vậy, nếu bạn sử dụng @EXPORT và ai đó thông thường use YourModule;, sau đó bạn vừa ô nhiễm không gian tên của họ với tất cả mọi thứ trong @EXPORT. Tuy nhiên, nếu bạn sử dụng @EXPORT_OK, họ phải yêu cầu cụ thể cho những thứ được nhập để người dùng mô-đun của bạn có quyền kiểm soát những gì xảy ra với không gian tên của họ.

Sự khác biệt thực sự là một vấn đề của người kiểm soát những gì được vào không gian tên các use r của: nếu bạn sử dụng @EXPORT sau đó các module là use d không, nếu bạn sử dụng @EXPORT_OK sau đó mã làm việc nhập khẩu điều khiển không gian tên riêng của họ.

Tất nhiên, bạn luôn có thể nói use Whatever(); để giữ mô-đun bất lịch sự làm ô nhiễm không gian tên của bạn nhưng điều đó rất xấu và bạn không cần phải kludge xung quanh mã thô lỗ muốn viết nguệch ngoạc trên không gian tên của bạn.

+0

Vì vậy,' sử dụng YourModule qw (ab); 'và' @EXPORT qw (ab); 'là vô nghĩa? Nếu không thì tôi vẫn không thấy lý do tại sao chúng ta cần '@ EXPORT_OK' – Jim

+3

@Jim' @ EXPORT' của chúng tôi giữ các biểu tượng bạn xuất theo mặc định (có nghĩa là, với 'sử dụng YourModule;'). Làm điều này được coi là một * thực hành xấu *. '@ EXPORT_OK' chứa danh sách tất cả các ký hiệu * có thể * được xuất khi yêu cầu rõ ràng. – amon

35

Giả sử tôi có gói MyPackage sử dụng @EXPORT.

#this is MyPackage.pm 
package MyPackage; 
@EXPORT = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

Bây giờ, khi tôi sử dụng MyPackage trong mã của tôi,

#this is myscript.pl 
use MyPackage; 

do_awesome_thing(); #works 

be_awesome(); #doesn't work 
MyPackage::be_awesome(); #works 

do_awesome_thing được tự động xuất khẩu sang mã của tôi từ MyPackage, mà không có tôi phải nói "đưa cái này cho tôi". be_awesome không được xuất khẩu (và nó sẽ không được xuất khẩu với @EXPORT_OK hoặc là, tôi chỉ hiển thị phần đó để giúp bạn rõ ràng về những gì "xuất khẩu" cung cấp cho chúng tôi).

Mặt khác, nếu tôi có một gói MyOtherPackage sử dụng @EXPORT_OK,

#this is MyOtherPackage.pm 
package MyOtherPackage; 
@EXPORT_OK = qw(do_awesome_thing); 

sub do_awesome_thing { ... } 

sub be_awesome { ... } 

và sau đó thử

#this is mynewscript.pl 
use MyOtherPackage; 

do_awesome_thing(); #doesn't work 
MyOtherPackage::do_awesome_thing(); #works, as always 

dòng gọi do_awesome_thing trực tiếp sẽ không hoạt động. Điều này là do việc đặt nội dung nào đó vào số @EXPORT_OK cho biết "chỉ cung cấp cho người dùng của tôi nếu họ yêu cầu". Vì chúng tôi vừa nói use MyOtherPackage mà không yêu cầu một cách rõ ràng cho do_awesome_thing để được nhập ở đây, nó không được nhập và chỉ có thể truy cập bằng cách chỉ định tên gói.

Cách bạn yêu cầu nhập do_awesome_thing để nói use MyOtherPackage qw(do_awesome_thing) ở dòng thứ hai là mynewscript.pl ở trên. Điều này cho biết nhập mô-đun đó và thực hiện trực tiếp do_awesome_thing. Sau đó, dòng thứ tư trong số mynewscript.pl ở trên sẽ bắt đầu hoạt động.

Lưu ý rằng người dùng có thể chỉ định use MyPackage qw(do_awesome_thing) với gói đầu tiên và trong trường hợp đó, bất kỳ điều gì khác trong danh sách @EXPORT sẽ không được xuất, chỉ do_awesome_thing sẽ là. Vì vậy, ngoại trừ trường hợp mặc định là use PackageName;, @EXPORT@EXPORT_OK hoạt động tương tự. Trong trường hợp mặc định, mọi thứ trong @EXPORT được tự động nhập vào tập lệnh của người dùng, trong khi @EXPORT_OK lịch sự hơn và không xuất bất kỳ thứ gì.

+4

* Với @EXPORT, bạn chỉ có hai lựa chọn * ... sai; chỉ là sai. '@ EXPORT' và' @ EXPORT_OK' hoạt động chủ yếu giống nhau: trong cả hai trường hợp, người dùng có thể chỉ định danh sách tên họ muốn nhập. Họ * chỉ * khác với những gì xảy ra khi người dùng cung cấp * không có danh sách tên cần nhập * - trong tình huống đó, mọi thứ trên '@ EXPORT' được xuất và mọi thứ trên' @ EXPORT_OK' thì không. – tobyink

+1

@tobyink Cảm ơn, đã không làm việc với XUẤT KHẨU nhiều nên không biết điều đó, tôi đã thay đổi phần đó ngay bây giờ. Trong khi Googling để xác nhận điều này tôi đã xem qua cuốn sách O'Reilly này (http://docstore.mik.ua/orelly/perl/advprog/ch06_05.htm) mà dường như làm cho cùng một sai lầm tôi đã làm: "Nếu module sử dụng xuất khẩu thay vì EXPORT_OK, người dùng nhận được tất cả các ký hiệu đã xuất, bất kể chúng có được đề cập trong danh sách nhập hay không. " Nhưng tôi đã thử nghiệm hành vi và xác nhận rằng bạn đã đúng và cuốn sách (rõ ràng) sai. – sundar

Các vấn đề liên quan