Soru perl olarak export_ok ihracatı


Fark / kullanım durumunun ne olduğunu anlayamıyorum EXPORT_OK vs EXPORT.
Çoğu kaynak şu satırlarda bir şeyden söz eder:

@Export, modüllerin işlevlerini ve değişkenlerini dışa aktarmaya izin verir.   Standart içe aktarma yöntemini kullanarak kullanıcının ad alanı. Bu şekilde, biz yapmayız   modüllere üyelerine ulaşmak için nesneler yaratmanız gerekir.
  @EXPORT_OK, seçici liste için talep bazında sembollerin ihracatını yapar   Modülün sembollerinin (alt rutinleri ve değişkenleri) gösterimi.

Ama ben gerçekten burada farkı / anlamı görmüyorum.
Birisi, bu 2 sembolün fark / kullanımının küçük bir temel örneğini verebilir mi?


25
2017-07-28 20:11


Menşei


Varsa, varsayılan olarak birçok sembolü dışa aktarmamalısınız. @EXPORT genellikle küçük veya boş olacaktır. @EXPORT_OK daha fazlasını içerebilir. Örneğin, Encode dışa aktarma encode ve decode varsayılan olarak (@EXPORT), Ama değil is_utf8 (@EXPORT_OK) - ikegami


Cevaplar:


Diyelim ki bir paketim var MyPackage kullanır @EXPORT.

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

sub do_awesome_thing { ... }

sub be_awesome { ... }

Şimdi, kullandığım zaman MyPackage benim kodumda

#this is myscript.pl
use MyPackage;

do_awesome_thing(); #works

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

do_awesome_thing otomatik olarak koduma aktarılıyor MyPackage, bana "bunu bana ver" demeden. be_awesome dışa aktarılmadı (ve dışa aktarılmayacak @EXPORT_OK Ya da, "ihracat" ın bize ne verdiğini açıklığa kavuşturmak için bu kısmı gösteriyorum.

Öte yandan, eğer bir paketim varsa MyOtherPackage kullanır @EXPORT_OK,

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

sub do_awesome_thing { ... }

sub be_awesome { ... }

ve sonra dene

#this is mynewscript.pl
use MyOtherPackage;

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

hat çağırıyor do_awesome_thing doğrudan çalışmaz. Bunun için bir şey koymak çünkü @EXPORT_OK "bunu kullanıcılarına ancak bunu isterlerse ver" diyor. Sadece söylediğimizden beri use MyOtherPackage açıkça sormadan do_awesome_thing Burada içe aktarılacak, içe aktarılmaz ve yalnızca paket adını belirterek erişilebilir.

İstediğin gibi do_awesome_thing ithal edilmek demek use MyOtherPackage qw(do_awesome_thing) ikinci satırında mynewscript.pl Yukarıdaki. Bu, bu modülün içe aktarıldığını ve yapıldığını söylüyor do_awesome_thing doğrudan kullanılabilir. Bundan sonra dördüncü satır mynewscript.pl yukarıda çalışmaya başlayacaktır.

Kullanıcının belirleyebileceğini unutmayın use MyPackage qw(do_awesome_thing) Ayrıca ilk paket ile, ve bu durumda, başka bir şey @EXPORT liste sadece ihraç edilmeyecek do_awesome_thing olacak. Yani, varsayılan durumun dışında use PackageName;, @EXPORT ve @EXPORT_OK benzer davranmak. Varsayılan durumda @EXPORT kullanıcının betiğine otomatik olarak atılır, @EXPORT_OK daha kibar ve hiçbir şey ihraç etmiyor.


37
2017-07-28 22:00



@EXPORT ile sadece iki seçeneğiniz var... yanlış; sadece yanlış. @EXPORT ve @EXPORT_OK çoğunlukla aynı şekilde çalışır: her iki durumda da kullanıcı, ithal etmek istedikleri isimleri belirleyebilir. Onlar bir tek kullanıcı sunduğunda ne olduğu farklı içe aktarılacak adların listesi yok - bu durumda, işler @EXPORT ihraç edilir ve işler @EXPORT_OK değiller. - tobyink
@tobyink Teşekkürler, EXPORT ile fazla çalışmadım, bu yüzden bilmiyordum, şimdi bu bölümü değiştirdim. Googling'i onaylamak için bu O'Reilly kitabına rastladım (docstore.mik.ua/orelly/perl/advprog/ch06_05.htm) Aynı hatayı yaptığım gibi görünüyor: "Eğer modül EXPORT_OK yerine EXPORT kullanıyorsa, kullanıcı ithalat listesinde belirtilip belirtilmediğine bakılmaksızın tüm dışa aktarılan sembolleri alır." Ama davranışları test ettim ve doğru ve kitabın (görünüşte) yanlış olduğunu doğruladım. - sundar


İtibaren ince ihracatçı kılavuzu:

  • use YourModule;
      Bu, YourModule’deki tüm sembolleri içe aktarır. @EXPORT ad alanının içine kullanım Beyan.
  • use YourModule ();
      Bu, perl'in modülünüzü yüklemesine neden olur, ancak herhangi bir simge içe aktarmaz.
  • use YourModule qw(...);
      Bu, yalnızca arayan tarafından ad alanlarına listelenen sembolleri içe aktarır. Listelenen tüm semboller sizin @EXPORT veya @EXPORT_OK, başka bir hata oluşur. İhracatçı'nın gelişmiş ihracat özelliklerine bu şekilde erişilir, ancak sembol isimlerinden sözdizimsel olarak farklı olan liste girişleri ile.

Eğer kullanırsanız @EXPORT ve her zamanki gibi use YourModule;Sonra da adlarını her şeyle kirlettin. @EXPORT. Ama, eğer kullanırsanız @EXPORT_OKÖzellikle, nesnelerin içe aktarılmasını istemek zorundadırlar. Böylece, modülünüzü kullanan kişinin ad alanlarına ne olduğu konusunda kontrolü vardır.

Fark gerçekten, kimin içine gireceğini kontrol eden bir meseledir. user'ın ad alanı: eğer kullanırsanız @EXPORT sonra modül used kullanırsanız @EXPORT_OK daha sonra ithalat yapan kod kendi ad alanını kontrol eder.

Tabii ki her zaman söyleyebilirsin. use Whatever(); Sahte modülleri ad alanınızı kirletmekten sakınmak için ama çirkin ve ad alanının her yerine karalamak isteyen kaba bir kodun etrafından dolaşmak zorunda kalmamalısınız.


16
2017-07-28 20:26



Yani use YourModule qw(a b); ve @EXPORT qw(a b); anlamsız? Eğer değilse, neden ihtiyacımız olduğunu hala göremiyorum. @EXPORT_OK - Jim
@Jim our @EXPORT dışa aktardığınız sembolleri varsayılan olarak (yani use YourModule;). Bunu yapmak bir kötü uygulama. @EXPORT_OK tüm sembollerin bir listesini tutar kutu açık talep üzerine ihraç edilmelidir. - amon