2016-07-05 13 views
9

Ich habe ein Modul namens hsfSubs.pm in meinem perl\lib Ordner. Ich habe nichts im Modul aber Unterprogramme und 1; am Ende.In Perl, warum brauche ich Exporter?

Ein Unterprogramm heißt zum Beispiel pause. Ich habe keine Import- oder Exportroutinen implementiert.

In meinen Hauptprogrammen sage ich einfach use hsfSubs;, und ich bin danach in der Lage, pause ohne Problem anzurufen. Dito, wenn ich sage use hsfSubs qw(pause);.

Warum sollte ich Exporteur, @EXPORT und @EXPORT_OK, etc. oder irgendwelche anderen Komplikationen verwenden?

Die mehreren Antworten auf Stack Overflow zu Fragen über Exporter sagen, wie man es verwendet, aber ich verstehe nicht, warum es zu verwenden.

Antwort

13

Die kurze Version ist, dass Sie ein Modul wollten, aber Sie endete mit dem, was this eine Bibliothek aufruft. Diese sind nicht gut, weil sie den Namespace ihres Aufrufers verschmutzen (was zu vielen Problemen führen kann). Aber wichtiger ist hier, laden sie mit require oder use (wie do entgegengesetzt) ​​ist fehlerhaft.

Wenn es richtig als Modul geschrieben wurde, würde Ihr Beispiel nicht funktionieren. Exporter ist die Lösung für dieses Problem.


Lassen Sie uns in die Details tauchen.

Wie gesagt, es gibt ein Problem mit Ihrem Modul. Wie Sie bemerkt haben, funktioniert es manchmal trotz des Fehlers.

$ cat Buggy.pm 
sub test { "ok!" } 
1; 

$ perl -e'use Buggy; CORE::say(test());' 
ok! 

Aber das ist nur, weil Ihr Beispiel zu einfach ist. Fügen wir dem Mix ein korrekt geschriebenes [1] Modul hinzu.

$ cat Buggy.pm 
sub test { "ok!" } 
1; 

$ cat Other.pm 
package Other; 
use Buggy; 
1; 

$ perl -e'use Other; use Buggy; CORE::say(test());' 
Undefined subroutine &main::test called at -e line 1. 

Der Fehler in Ihrem Modul ist, dass es keine package Richtlinie hat. Module, die mit use und require geladen werden, müssen immer eine package Direktive verwenden. Aber sobald Sie das hinzufügen, funktioniert Ihr Modul nicht mehr.

$ cat NotBuggy.pm 
package NotBuggy; 
sub test { "ok!" } 
1; 

$ perl -e'use NotBuggy; CORE::say(test());' 
Undefined subroutine &main::test called at -e line 1. 

Exporteur wird verwendet, um dieses Problem zu lösen.

$ cat Final.pm 
package Final; 
use Exporter qw(import); 
our @EXPORT = qw(test); 
sub test { "ok!" } 
1; 

$ perl -e'use Final; CORE::say(test());' 
ok! 

  1. Nun, nicht wirklich. Wenn es richtig geschrieben wurde, würde es Verwendung use strict; use warnings 'all'; enthalten. Nimm das immer mit! Es wurde hier weggelassen, um die Dinge optisch einfach zu halten.
+0

Danke. Ich sehe den Unterschied. Aber eine "Bibliothek" ist wirklich, was ich wollte. Der einzige Grund, warum ich ein Modul möchte, ist, wenn es keine andere Möglichkeit gibt, eine Bibliothek zu bekommen. Es ist irgendwie komisch zu sagen, dass es nicht funktionieren würde, wenn ich es richtig geschrieben hätte. LOL. Ich nehme an, "Verschmutzung" ist im Kopf des Betrachters. Ich denke nicht, dass ich Zugang zu meinen eigenen Subroutinen als Umweltverschmutzung habe. Unnötige Komplexität ist Verschmutzung. – user1067305

+1

Verschmutzung ist nicht das Vorhandensein von gesuchten Dingen; es ist die Anwesenheit von unerwünschten Dingen.Das Problem besteht darin, dass Sie nicht nur auf die Subs zugreifen können, die Sie exportieren möchten, sondern auch auf Subs, die ebenfalls in Ihrem Modul enthalten sind. Es ist das Sub-Äquivalent von globalen Variablen. Bei der Programmierung geht es darum, den Umfang zu begrenzen, das genaue Gegenteil von dem, was Sie gesagt haben, ist gut. Alles global zu machen, macht das Lesen, Debuggen, Pflegen usw. schwierig. Nein, das ist kein Stilproblem. Die Gesamtheit der Perl-Programmierer hörte auf, diese "Bibliotheken" zu verwenden, als Perl vor 20 Jahren Unterstützung für die Namespace-Unterstützung hinzufügte. – ikegami

+6

Lange Rede, kurzer Sinn, die Aufgliederung Ihres Codes erfordert ein wenig zusätzlichen Code, macht das Programm jedoch * viel * komplexer. – ikegami