require#
Φορτώνει ένα αρχείο πηγαίου κώδικα Perl σε χρόνο εκτέλεσης, ή απαιτεί μια ελάχιστη έκδοση Perl.
Η require έχει τρεις μορφές που κάνουν αρκετά διαφορετικά πράγματα. Με αριθμό έκδοσης επιβεβαιώνει ότι ο τρέχων διερμηνέας είναι αρκετά νέος. Με bareword φορτώνει ένα άρθρωμα μετατρέποντας το Foo::Bar σε Foo/Bar.pm και αναζητώντας στο @INC. Με συμβολοσειρά κατά τον χρόνο εκτέλεσης ή με $_ φορτώνει ένα όνομα αρχείου ως έχει. Και οι τρεις είναι λειτουργίες χρόνου εκτέλεσης - αντίθετα με την use, που είναι require + import τυλιγμένα σε ένα μπλοκ BEGIN κατά τη μεταγλώττιση.
Σύνοψη#
require VERSION
require EXPR
require
Τι επιστρέφεται#
Για τη μορφή ελέγχου έκδοσης: 1 αν η τρέχουσα Perl είναι αρκετά νέα· διαφορετικά εκτοξεύεται εξαίρεση (Perl vX.Y.Z required--this is only ...). Δεν υπάρχει τίποτα προς έλεγχο.
Για τις μορφές φόρτωσης αρχείων: η αληθής τιμή που επιστρέφει η τελευταία δήλωση του φορτωμένου αρχείου, ή 1 αν το αρχείο ενεργοποιεί το χαρακτηριστικό module_true (προεπιλεγμένο υπό use v5.38 και μεταγενέστερα). Μια δεύτερη require της ίδιας διαδρομής επιστρέφει 1 χωρίς να επανεκτελέσει το αρχείο. Η αποτυχία εκτοξεύει εξαίρεση - είτε το σφάλμα μεταγλώττισης/χρόνου εκτέλεσης από το αρχείο, Can't locate Foo/Bar.pm in @INC ..., ή Foo/Bar.pm did not return true value.
Τυλίξτε σε eval όταν θέλετε να ελέγξετε αν ένα άρθρωμα είναι φορτώσιμο:
eval { require Some::Optional::Module };
if ($@) { ... } # module missing or broken
Καθολική κατάσταση που επηρεάζει#
@INC- η διαδρομή αναζήτησης για τις μορφές bareword και σχετικού ονόματος αρχείου. Οι εγγραφές μπορεί να είναι συμβολοσειρές καταλόγων, coderefs, αναφορές πινάκων, ή blessed αντικείμενα (δείτε Γάντζοι@INCπαρακάτω).%INC- αντιστοιχίζει το ζητούμενο όνομα αρχείου (Foo/Bar.pm) στην απόλυτη διαδρομή που φορτώθηκε. Ηrequireτη συμβουλεύεται για να αποφύγει διπλή φόρτωση και τη θέτει σε επιτυχία. Εγγραφή με τιμήundefσημαδεύει αρχείο του οποίου η μεταγλώττιση απέτυχε.$_- χρησιμοποιείται ως όνομα αρχείου όταν ηrequireκαλείται χωρίς όρισμα.${^HOOK}{require__before}και${^HOOK}{require__after}- προαιρετικά coderefs που εκτελούνται γύρω από κάθεrequire, διαθέσιμα για περιτυλίγματα ιχνηλασίας και οργανολογίας.
Οι τρεις μορφές#
require VERSION - έλεγχος ελάχιστης Perl#
Το VERSION είναι είτε v-string όπως v5.38.0 (συγκρίνεται έναντι της $^V) ή αριθμητικό κυριολεκτικό όπως 5.038000 (συγκρίνεται έναντι της $]). Αν ο τρέχων διερμηνέας είναι παλαιότερος, η require εκτοξεύει εξαίρεση.
require v5.38; # preferred
require 5.038; # numeric; same effect
require 5.038_000; # same; pre-5.6 syntax
Αυτός είναι έλεγχος χρόνου εκτέλεσης. Αν θέλετε ο έλεγχος να γίνει κατά τη μεταγλώττιση (ώστε το σενάριο να μην εκκινεί ποτέ σε παλιά Perl), χρησιμοποιήστε αντί αυτής use VERSION:
use v5.38; # compile-time equivalent
require EXPR όπου το EXPR είναι bareword - άρθρωμα κατ” όνομα#
Ένα bareword ερμηνεύεται ως όνομα αρθρώματος. Η require αντικαθιστά κάθε :: με / και προσαρτά .pm, και στη συνέχεια αναζητά στο @INC:
require Foo::Bar; # looks for Foo/Bar.pm in @INC
Αυτή η μορφή επίσης αυτο-δημιουργεί τη stash κατά τη μεταγλώττιση - το hash πακέτου Foo::Bar:: εμφανίζεται ακόμη και αν η φόρτωση αποτύχει μετέπειτα. Δεν εισάγονται σύμβολα· η require μόνο φορτώνει κώδικα.
Πριν δοκιμάσει το Foo/Bar.pm, η require ψάχνει για το Foo/Bar.pmc στον ίδιο κατάλογο και το προτιμά αν το βρει. Ο γάντζος .pmc επιτρέπει σε εργαλεία build να αποστέλλουν προμεταγλωττισμένα συνοδευτικά αρχεία δίπλα στις πηγές.
require EXPR όπου το EXPR είναι συμβολοσειρά - αρχείο κατά διαδρομή#
Οποιαδήποτε έκφραση που δεν είναι bareword αντιμετωπίζεται ως κυριολεκτικό όνομα αρχείου. Καμία μετατροπή ::, καμία προσάρτηση .pm, καμία αυτο-δημιουργία stash:
require "Foo/Bar.pm"; # explicit .pm path
require "$config_dir/init.pl"; # arbitrary filename
my $class = 'Foo::Bar';
require $class; # ERROR: looks for file "Foo::Bar"
Η τελευταία γραμμή είναι η κλασική παγίδα: μόλις το όνομα του αρθρώματος βρίσκεται σε βαθμωτό, είναι συμβολοσειρά, όχι bareword. Για να φορτώσετε άρθρωμα του οποίου το όνομα υπολογίζεται, είτε κάντε τη μετατροπή εσείς, είτε περάστε από eval:
(my $file = "$class.pm") =~ s{::}{/}g;
require $file;
eval "require $class; 1" or die $@;
Αν το EXPR παραλειφθεί εντελώς, χρησιμοποιείται η $_.
Η προστασία του %INC - τα φορτωμένα αρχεία παραμένουν φορτωμένα#
Πριν αναζητήσει στο @INC, η require συμβουλεύεται το %INC. Αν το ζητούμενο όνομα αρχείου είναι παρόν και έχει αληθή τιμή, η require επιστρέφει αμέσως 1 χωρίς να ξαναδιαβάσει το αρχείο. Αν η τιμή είναι undef, μια προηγούμενη φόρτωση απέτυχε και η require εκτοξεύει Compilation failed in require - η Perl αρνείται να ξαναδοκιμάσει ένα αρχείο που έχει ήδη εκραγεί μία φορά σε αυτόν τον διερμηνέα.
Αυτό σημαίνει ότι ο κώδικας ανώτατου επιπέδου ενός αρθρώματος εκτελείται ακριβώς μία φορά ανά διερμηνέα, ανεξάρτητα από το από πόσα μέρη γίνεται require. Η αρχικοποίηση στο σώμα του αρχείου του αρθρώματος είναι μονή λειτουργία· μη βασίζεστε στο ότι θα τρέχει για κάθε κλήση require σε κάθε καλούντα.
Ένας γάντζος είναι ελεύθερος να θέσει ο ίδιος το %INC· αν δεν το κάνει, η require καταγράφει τον γάντζο ως «πηγή» της φόρτωσης.
Η σύμβαση του 1;#
Ιστορικά, κάθε φορτώσιμο αρχείο έπρεπε να επιστρέφει αληθή τιμή ως τελευταία του έκφραση, διαφορετικά η require εκτόξευε filename did not return true value. Ο καθιερωμένος τρόπος για να το εγγυηθεί κανείς είναι ένα τελικό 1;:
package My::Thing;
# ... module code ...
1; # mandatory, pre-5.38
Από την Perl 5.38, το χαρακτηριστικό module_true - προεπιλεγμένα ενεργοποιημένο υπό use v5.38 ή μεταγενέστερα - κάνει κάθε αρχείο που γίνεται require να επιστρέφει σιωπηρά αληθές σε επιτυχημένη μεταγλώττιση. Τα αρχεία που το ενεργοποιούν δεν χρειάζονται πλέον 1;. Όσα όχι, εξακολουθούν να το χρειάζονται.
Αυτό επηρεάζει μόνο τη μονάδα μεταγλώττισης που ενεργοποίησε το χαρακτηριστικό· παλαιά αρθρώματα που φορτώνονται από σύγχρονο καλούντα εξακολουθούν να χρειάζονται το δικό τους 1;.
Όταν το φορτωμένο αρχείο επιστρέφει τιμή και το module_true είναι ανενεργό, αυτή η τιμή είναι αυτό που επιστρέφει η require - αλλά μόνο στην πρώτη φόρτωση. Επόμενες κλήσεις require του ίδιου αρχείου επιστρέφουν 1 από την προσωρινή μνήμη του %INC. Για να αποτυπώσετε αξιόπιστα την τιμή επιστροφής ενός αρχείου, χρησιμοποιήστε do:
my $config = do "config.pl"
or die "config.pl: ", $@ || $!;
Γάντζοι @INC - coderefs, αναφορές πινάκων, και αντικείμενα#
Οι εγγραφές στο @INC δεν χρειάζεται να είναι συμβολοσειρές καταλόγων. Μια αναφορά αποθηκευμένη στο @INC καλείται γάντζος και έχει την ευκαιρία να ικανοποιήσει την require.
Αναφορά υπορουτίνας#
Καλείται με δύο ορίσματα: το ίδιο το coderef και το όνομα αρχείου (Foo/Bar.pm). Πρέπει να επιστρέφει είτε τίποτα (που σημαίνει «δεν μπορώ να το χειριστώ αυτό· δοκίμασε την επόμενη εγγραφή») είτε μέχρι τέσσερις τιμές:
Μια βαθμωτή αναφορά σε κείμενο πηγαίου κώδικα που προτάσσεται στο αρχείο.
Ένα filehandle από το οποίο διαβάζεται ο υπόλοιπος πηγαίος κώδικας.
Μια υπορουτίνα γεννήτορα ή φίλτρου (δείτε το
perldoc perlfuncγια το ακριβές πρωτόκολλο).Προαιρετική κατάσταση που μεταβιβάζεται πίσω στον γεννήτορα.
push @INC, sub {
my ($self, $filename) = @_;
return unless $filename eq 'Virtual/Module.pm';
open my $fh, '<', \"package Virtual::Module; 1;";
return $fh;
};
Αναφορά πίνακα#
Το πρώτο στοιχείο είναι coderef ή αντικείμενο όπως παραπάνω· το υπόλοιπο είναι κατάσταση που ο γάντζος μπορεί να διαβάζει σε κάθε κλήση. Όταν το πρώτο στοιχείο είναι αντικείμενο με μέθοδο INC ή INCDIR, η μέθοδος λαμβάνει την αναφορά πίνακα ως τρίτο της όρισμα.
push @INC, [\&my_loader, $db_handle, $cache];
Blessed αντικείμενο#
Αν το αντικείμενο έχει μέθοδο INC ή INCDIR, η require καλεί αυτή τη μέθοδο· διαφορετικά, αν το αντικείμενο είναι επίσης coderef, καλείται σαν απλή αναφορά υπορουτίνας. Οι μέθοδοι INC πρέπει να δηλώνονται με το πλήρως κατονομασμένο όνομά τους (sub Foo::INC { ... }), διότι το ακατονόμαστο σύμβολο INC είναι σταθερά συνδεδεμένο με το πακέτο main.
Ένας γάντζος είναι ελεύθερος να ενημερώσει το %INC ώστε να καταγράψει τη διαδρομή που παρείχε· αν δεν το κάνει, η require αποθηκεύει την ίδια την αναφορά του γάντζου.
require έναντι use#
use Foo::Bar qw(x y);
# is almost exactly:
BEGIN {
require Foo::Bar;
Foo::Bar->import(qw(x y));
}
Πτυχή |
|
|
|---|---|---|
Πότε εκτελείται | Χρόνος μεταγλώττισης (μέσα σε | Χρόνος εκτέλεσης |
Καλεί την | Ναι | Όχι |
Bareword | Ναι | Ναι, όταν καλείται με bareword |
Μορφή ελέγχου έκδοσης |
|
|
Κατάλληλη για | Σταθερές εξαρτήσεις | Προαιρετικά / αργά συνδεόμενα αρθρώματα |
Καταφύγετε στην require όταν το άρθρωμα είναι προαιρετικό, φορτώνεται από όνομα που υπολογίζεται, ή φορτώνεται μόνο μέσα σε διακλάδωση που ίσως δεν εκτελεστεί ποτέ. Καταφύγετε στην use για όλα τα υπόλοιπα.
Παραδείγματα#
Ελάχιστη έκδοση Perl σε χρόνο εκτέλεσης:
require v5.38;
Φόρτωση αρθρώματος με bareword - αναζητά στο @INC, αυτο-δημιουργεί το Data::Dumper:: κατά τη μεταγλώττιση:
require Data::Dumper;
Data::Dumper->import;
print Data::Dumper::Dumper(\%ENV);
Προαιρετικό άρθρωμα - υποχωρήστε χαριτωμένα όταν λείπει:
my $have_json = eval { require JSON::PP; 1 };
if ($have_json) {
print JSON::PP->new->encode($data);
}
Φόρτωση αρθρώματος του οποίου το όνομα υπολογίζεται σε χρόνο εκτέλεσης. Μετατρέψτε σε διαδρομή ονόματος αρχείου· το require $class θα έψαχνε για ένα κυριολεκτικό αρχείο με όνομα Foo::Bar:
my $driver = $ENV{DB_DRIVER} // 'SQLite';
my $class = "DBD::$driver";
(my $file = "$class.pm") =~ s{::}{/}g;
require $file;
Φόρτωση αποσπάσματος ρυθμίσεων κατά διαδρομή, διατηρώντας την τιμή επιστροφής του - σημειώστε την do, όχι την require, διότι θέλουμε την τιμή σε κάθε κλήση:
my $config = do '/etc/myapp/config.pl'
or die "config load failed: ", $@ || $!;
Εγκατάσταση γάντζου @INC που εξυπηρετεί ένα μεμονωμένο εικονικό άρθρωμα από συμβολοσειρά στη μνήμη:
unshift @INC, sub {
my ($self, $filename) = @_;
return unless $filename eq 'MyApp/Version.pm';
my $src = "package MyApp::Version; our \$VERSION = '1.23'; 1;";
open my $fh, '<', \$src;
$INC{$filename} = '(generated)';
return $fh;
};
require MyApp::Version;
Οριακές περιπτώσεις#
Bareword έναντι συμβολοσειράς: τα
require Foo::Barκαιrequire "Foo::Bar"δεν είναι το ίδιο. Η μορφή bareword μετατρέπεται σεFoo/Bar.pm· η μορφή συμβολοσειράς αναζητά αρχείο με κυριολεκτικό όνομαFoo::Bar.Υπολογιζόμενα ονόματα κλάσεων: το
require $classόπου η$classκρατά'Foo::Bar'αναζητά αρχείο με όνομαFoo::Bar, όχιFoo/Bar.pm. Κάντε εσείς τη μετατροπή του ονόματος, ή χρησιμοποιήστεeval "require $class"όταν το όνομα είναι έμπιστο.Χωρίς όρισμα: η
require;χρησιμοποιεί την$_ως όνομα αρχείου. Σπάνιο σε σύγχρονο κώδικα· σχεδόν πάντα ατύχημα.Οι επανεκτελέσεις δεύτερης ευκαιρίας δεν λειτουργούν: Αν μια
requireαποτύχει στη μέση της μεταγλώττισης, το%INCκαταγράφειundefγια αυτό το όνομα αρχείου. Μια μεταγενέστερηrequireτου ίδιου ονόματος βλέπει τοundefκαι εκτοξεύειCompilation failed in requireχωρίς να ξανατρέξει το αρχείο. Διαγράψτε την εγγραφή του%INCαν θέλετε πραγματικά να ξαναδοκιμάσετε (αυτό είναι αιχμηρό άκρο· προτιμήστε να διορθώσετε την υποκείμενη αποτυχία).Αφαίρεση του σχετικού
.: το.αφαιρέθηκε από το προεπιλεγμένο@INCστην Perl 5.26. Ένα σενάριο που παλιά έβρισκε τοFoo/Bar.pmδίπλα του πρέπει τώρα να προσθέτει ρητά τον δικό του κατάλογο (use FindBin; use lib $FindBin::Bin;).Σκίαση
.pmc: αν τοFoo/Bar.pmcυπάρχει στον ίδιο κατάλογο με τοFoo/Bar.pm, το.pmcυπερισχύει. Τα παλιωμένα αρχεία.pmcείναι κλασική παγίδα τύπου «γιατί η επεξεργασία μου δεν έχει αποτέλεσμα».Ανάλυση του
require(EXPR): ηrequireαναλύεται ως ονομαστικός μοναδιαίος τελεστής· τοrequire EXPR + 1σημαίνειrequire(EXPR + 1). Χρησιμοποιήστε ρητές παρενθέσεις όταν το όρισμα είναι μη τετριμμένη έκφραση.Αυτο-δημιουργία stash: το
require Foo::Barδημιουργεί τη stashFoo::Bar::ακόμη και αν το αρχείο λείπει. Επόμενοι έλεγχοιdefined &Foo::Bar::some_subμπορεί να περάσουν το στάδιο «το πακέτο υπάρχει» αλλά να αποτύχουν στο στάδιο «η υπορουτίνα υπάρχει».Το filehandle από γάντζο πρέπει να είναι πραγματικό: Τα tied filehandles αγνοούνται σιωπηλά από το πρωτόκολλο γάντζων· η επεξεργασία ξεπέφτει από το τέλος και η
requireαναφέρει «not found». Χρησιμοποιήστε πραγματικό typeglob.Το
INCπρέπει να είναι πλήρως κατονομασμένο σε κλάσεις γάντζων: τοsub Foo::INC { ... }λειτουργεί· τοsub INC { ... }μέσα σεpackage Fooεγκαθιστά τοmain::INCλόγω ενός σταθερά κωδικοποιημένου κανόνα πακέτου.Η
require()είναι δύσκολο να περιτυλιχθεί: Πολλά αρθρώματα επιθεωρούν τη στοίβα κλήσεων για να βρουν τον καλούντα τους. Ένα περιτύλιγμα που προσθέτει πλαίσιο συχνά τα σπάει. Προτιμήστε τους γάντζους${^HOOK}{require__before}/${^HOOK}{require__after}(προστέθηκαν στην 5.38) για ιχνηλασία.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
use-require+importκατά τη μεταγλώττιση· ο κανονικός τρόπος για να φέρετε ένα άρθρωμα από το οποίο εξαρτάστε ανεπιφύλακταdo- φορτώνει ένα αρχείο και επιστρέφει την τιμή του σε κάθε κλήση, χωρίς αποθήκευση στο%INCκαι χωρίς τον κανόνα «πρέπει να επιστρέψει αληθές»import- η μέθοδος που καλεί ηuseμετά τηνrequire· ηrequireδεν την καλεί ποτέ για εσάς@INC- διαδρομή αναζήτησης που συμβουλεύεται για φορτώσεις με bareword και σχετικό όνομα αρχείου· δέχεται συμβολοσειρές καταλόγων, coderefs, αναφορές πινάκων και αντικείμενα ως γάντζους%INC- προσωρινή μνήμη μίας εγγραφής ανά φορτωμένο αρχείο, που κάνει τηνrequireιδεμπoτή και καταγράφει από πού ήρθε κάθε άρθρωμαeval- τυλίξτε τηνrequireόταν επιτρέπεται η φόρτωση να αποτύχει