(PERL Module) require vs. use
Christoph
Hallo Zusammen,
ich versuche gerade verzweifelt Mime::Lite auf einem Server zu installieren, auf dem ich keinerlei root-Rechte habe.
Ich habe in der cgibin ein Unterverzeichnis angelegt und die Datei Lite.pm hineinkkopiert.
Wenn ich das Modul jetzt mit require ".library/Lite.pm" lade, kann ich es problemlos benutzen. Mit
use lib "./library/";
use Mime::Lite;
erreichte ich nur die Fehlermeldung "Can't locate Mime/Lite.pm in @INC at ...".
Meine Fragen dazu:
Wann reicht require aus? Kann es zu Problemen kommen? (Immerhin laeuft es ja so!)
was ist falsch an meinem "use lib ..." das ich in einem frueheren Thread als "Loesung" gefunden habe.
Gruss und Dank,
Chris
Moin Chris!
Ich habe in der cgibin ein Unterverzeichnis angelegt und die Datei Lite.pm hineinkkopiert.
Du solltest in dem Unterverzeichnis noch ein Verzeichnis "Mime" anlegen und dort dann die Datei hinkopieren.
Wenn ich das Modul jetzt mit require ".library/Lite.pm" lade, kann ich es problemlos benutzen. Mit
»»
use lib "./library/";
use Mime::Lite;
»»
erreichte ich nur die Fehlermeldung "Can't locate Mime/Lite.pm in @INC at ...".
Ja, denn diese Zeile ist (ungefaehr) gleichbedeutend mit
require "Mime/Lite.pm";
Da es diesen Pfad bei Dir aber nicht gibt (weil Du ja das Verzeichnis Mime nicht angelegt hattest), kann die Datei nicht gefunden werden. Aber bitte verwende jetzt nicht einfach
use Lite;
! Die Datei wuerde dann zwar gefunden werden, aber jenachdem, wie das Modul programmiert ist, kann Sie nicht richtig verarbeitet werden, da dann erwartet wird, dass es das Modul "Lite" ist, nicht "Mime::Lite".
- Wann reicht require aus? Kann es zu Problemen kommen? (Immerhin laeuft es ja so!)
Du kannst hinter require genauso wie hinter use einfach den puren Modulnamen angeben. require sucht dann aber in derselben Weise nach der Datei Mime/Lite.pm. Dahingehend besteht also kein Unterschied. use wird aber im Gegensatz zu require immer gleich zu Beginn des Scripts ausgefuehrt, noch vor der ersten "richtigen" Codezeile. (Man sagt auch "zur Compilierzeit".) Ausserdem beinhaltet use auch noch automatisch den Aufruf
import Mime::Lite;
Was das bedeutet, will ich jetzt aber mal nicht erklaeren, das steht naemlich auch alles in
perldoc perlfunc
bei require, use und import.
- was ist falsch an meinem "use lib ..." das ich in einem frueheren Thread als "Loesung" gefunden habe.
Daran ist nichts falsch.
HTH && So long
P.S. In Berlin scheint jetzt wieder die Sonne! Naja, das SelfTreffen ist ja nun auch vorbei ... ;-)
P.S. In Berlin scheint jetzt wieder die Sonne! Naja, das
SelfTreffen ist ja nun auch vorbei ... ;-)
Hier in London scheint die Sonne ebenfalls. Vielen Dank fuer Deine Hilfe.
Chris
Hallo,
zuerstmal einige Quellen-Angaben:
[1] perldoc -f use Beschreibung von 'use'
[2] perldoc -f require Beschreibung von 'require'
[3] perldoc -f import Bechreibung von 'import'
[4] perldoc perlmod Beschreibung wie Module behandelt werden
Obwohl es eigentlich nicht wirklich Dein Problem ist, möchte ich diesen Anlaß nutzen, einige Worte zu 'use' und 'require' zu verlieren.
Es gibt eigentlich zwei wesenliche Unterschiede zw. 'use' und 'require':
1.) bei 'use' wird da Modul _immer_ am Beginn des Scripts eingbunden, bei 'require' dann, wenn die Funktion aufgerufen wird.
2.) bei require gibt es keinen Import von Namen.
<Erläuterungen>
laut [1] ist use mit folgender Code-Sequenz gleichzusetzen:
BEGIN { require Module; import Module LIST; }
zu 1.)
'BEGIN' bezeichnet ja den Block, der immer am Anfang (bzw. so früh, wie möglich) des Scripts ausgeführt wird.([4] Abschnitt 'Package Constructors and Destructors')
Oben angeführter 'Ersatz-Code' impliziert für use genau dieses Verhalten. D.h. egal wo das use steht, es wird in jedem Falle so früh, wie möglich gemacht. Nach meinen Beobachtungen _nach_ dem möglicherweise definierten BEGIN-Block.
Das 'require' erst dann ausgeführt wird, wenn die Funktion wirklich aufgerufen wird. Es kann auch vorkommen, daß sie nie ausgeführt wird, weil der Code-teil nicht angesprungen wird. das hat seine Vorteile, da es dadurch möglich ist, bestimmte Module nur dann einzubinden, wenn wirklich ihren Funktionalität benötigt wird.
In Deinem Beispiel könnte es sein, daß das Script vielleicht kein Mail versendet, weil etwas an den Angaben nicht stimmt, und daher nur eine Fehlermeldung ausgegeben werden muß. Dann ist es auch nicht notwendig, das Modul zu laden, was Performance bringt.
zu 2.)
Nach [4] ist 'import' keine eingebaute Funktion, sondern sollte, wenn notwendig, von dem Modul bereitgestellt werden, um Namen an andere Module zu exportieren. Es muß also nicht unbedingt sein, daß ein Modul nur mit 'use' eingebunden werden kann, um richtig zu funktionieren. CGI.pm besitzt z.B. diese Funktion, deshalb sollte sie der Einfachheit halber auch mit 'use' eingebunden werden.
Alternativ funktioniert auch:
require CGI;
import CGI qw/:standard/;
</Erläuterungen>
Dein Problem kommt aber von ganz wo anders. (uff, endlich kommt er zur Sache)
Wenn ich das Modul jetzt mit require ".library/Lite.pm" lade, kann ich es problemlos benutzen. Mit
ich glaube du meintest "./library/Lite.pm". Oder heißt der Ordner wirklich ".library"??
im Nächsten Teil nämlich nicht.
use lib "./library/";
use Mime::Lite;
'use' führt implizit ein 'require' aus, das steht ja schon weiter oben. nach [2] passiert bei 'require' folgendes:
Es durchsucht mittels @INC alle dort eingetragenen Verzeichnisse, und versucht die Datei einzubinden.
Quasi sowas:
<Vereinfachtes_snippet_aus_[2]>
foreach $prefix (@INC)
{
$realfilename = "$prefix/$filename";
if (-f $realfilename)
{
# einbinden
}
}
</Vereinfachtes_snippet_aus_[2]>
ein paar Zeilen weiter unten steht:
<CITE>
If EXPR is a bareword, the require assumes a .pm'' extension and replaces
::'' with ``/'' in the filename for you, to make it easy to load standard modules. This form of loading of modules does not risk altering your namespace. (EXPR ist der Modulname)
</CITE>
wenn Du nun
use Mime::Lite;
schreibst, dann _ist_ "Mime::Lite" ein BAREWORD. Deshalb ersetzt die Funktion '::' durch '/' und hängt ein '.pm' an. Das ergibt dann 'Mime/Lite.pm'.
in dem Snippet versucht die Funktion dann entsprechend Deiner @INC-Liste, das Modul zu finden. Es gibt aber kein './library//Mime/Lite.pm' sonder nur ein './library/Lite.pm'.
(die doppelt Slashes wären da nicht mal ein Problem, sollte aber auch nicht sein.)
Also bleibt nichts anderes übrig, als 'Lite.pm' in das Verzeichnis './library/Mime' zu stellen.
Dann noch
use lib 'library';
bzw:
use lib './library';
und wieder
use Mime::Lite;
Ein
use Lite;
würde nicht funktionieren. Aber das steht ja auch in [4].
So, das wars. Und dabei habe ich _nur_ in der mitgelieferten Dokumentation gelesen ;-)
Grüße
Klaus
Auch Dir vielen DANK! Das war wirklich ausfuehrlich und ich glaube jetzt habe ich es verstanden!
Chris
Wann reicht require aus? Kann es zu Problemen kommen? (Immerhin laeuft es ja so!)
was ist falsch an meinem "use lib ..." das ich in einem frueheren Thread als "Loesung" gefunden habe.
Das steht alles in perldoc -f use
und referenzierten PODs.