Ροή ελέγχου

FILE#

Το όνομα του αρχείου πηγαίου κώδικα στο οποίο μεταγλωττίζεται το διακριτικό.

Το __FILE__ είναι διακριτικό μεταγλώττισης, όχι συνάρτηση χρόνου εκτέλεσης. Στο σημείο όπου το διαβάζει ο μεταγλωττιστής, αντικαθίσταται από μια συμβολοσειρά κυριολεκτικής τιμής που περιέχει το όνομα αρχείου από το οποίο διαβάζει εκείνη τη στιγμή ο μεταγλωττιστής. Δεν δέχεται ορίσματα, δεν καλείται ποτέ με παρενθέσεις, και δεν έχει κόστος κατά τον χρόνο εκτέλεσης - μέχρι να εκτελεστεί το πρόγραμμά σας, το __FILE__ έχει ήδη γίνει μια απλή σταθερά συμβολοσειράς.

Η μοναδική του δουλειά είναι να επιτρέπει στον κώδικα να αναγνωρίζει το αρχείο στο οποίο βρίσκεται, για μηνύματα σφαλμάτων, γραμμές καταγραφής, διαγνωστικά δοκιμών, και παρόμοιες αναφορές.

Σύνοψη#

__FILE__

Τι επιστρέφεται#

Μια συμβολοσειρά: το όνομα αρχείου όπως το γνώριζε ο μεταγλωττιστής όταν διάβασε αυτό το διακριτικό. Για ένα σενάριο που καλείται ως perl /tmp/run.pl η τιμή είναι /tmp/run.pl· για ένα άρθρωμα που φορτώνεται μέσω require ή use είναι η διαδρομή που επέλυσε το require έναντι του @INC (συνήθως απόλυτη διαδρομή). Για κώδικα που τροφοδοτείται μέσω της τυπικής εισόδου ή μέσω -e είναι - ή -e αντίστοιχα.

Επειδή η αντικατάσταση γίνεται κατά τη μεταγλώττιση, η τιμή είναι σταθερή για κάθε κειμενική εμφάνιση του διακριτικού. Δύο διακριτικά __FILE__ σε διαφορετικά αρχεία παράγουν διαφορετικές συμβολοσειρές· δύο στο ίδιο αρχείο παράγουν την ίδια συμβολοσειρά.

Καθολική κατάσταση που επηρεάζει#

Καμία κατά τον χρόνο εκτέλεσης. Κατά τη μεταγλώττιση η τιμή λαμβάνεται από το τρέχον όνομα αρχείου του μεταγλωττιστή, που είναι η ίδια τιμή την οποία αναφέρει η caller σε περιβάλλον λίστας ως στοιχείο [1] και την οποία χρησιμοποιούν οι die / warn για να δομήσουν το προεπιλεγμένο τους επίθεμα "at FILE line LINE.".

Αυτό το όνομα αρχείου μπορεί να επανεγγραφεί από οδηγία #line ενσωματωμένη στον πηγαίο κώδικα - δείτε Οριακές περιπτώσεις παρακάτω. Μόλις επανεγγραφεί, τα διακριτικά __FILE__ που μεταγλωττίζονται μετά την οδηγία αναφέρουν το νέο όνομα.

Παραδείγματα#

Αναγνώριση του σεναρίου που εκτελείται σε μια γραμμή καταγραφής:

warn "started from ", __FILE__, "\n";
# started from /tmp/run.pl

Επισύναψη της θέσης στον πηγαίο κώδικα σε ένα προσαρμοσμένο σφάλμα χωρίς το προεπιλεγμένο επίθεμα της die:

sub fail {
    my ($msg) = @_;
    die sprintf("%s at %s line %d\n", $msg, __FILE__, __LINE__);
}

Δόμηση διαδρομής σχετικής με το τρέχον άρθρωμα, ώστε τα αρχεία πόρων να διανέμονται μαζί με τον κώδικα που τα φορτώνει:

use File::Basename qw(dirname);
use File::Spec;
my $data = File::Spec->catfile(dirname(__FILE__), "data.txt");

Χρησιμοποιήστε το __FILE__ μέσα σε μια συμβολοσειρά που περνά στην eval ώστε οι αναφορές σφαλμάτων να δείχνουν στον αρχικό πηγαίο κώδικα και όχι στον ανώνυμο ενταμιευτή (eval N):

my $code = qq[\n#line ] . __LINE__ . qq[ "] . __FILE__ . qq["\n]
         . q[die "boom"];
eval $code;
# boom at <current file> line <current line>.

Διάκριση μεταξύ «εκτελείται ως σενάριο» και «φορτώνεται ως άρθρωμα» - ο συνηθισμένος έλεγχος είναι αν το αρχείο κλήθηκε απευθείας:

__PACKAGE__->run(@ARGV) if __FILE__ eq $0;

Οριακές περιπτώσεις#

  • Κατά τη μεταγλώττιση, όχι κατά τον χρόνο εκτέλεσης. Το __FILE__ είναι διακριτικό που ο αναλυτής αντικαθιστά με κυριολεκτική συμβολοσειρά. Δεν είναι συνάρτηση από την οποία μπορείτε να πάρετε αναφορά· το \&__FILE__ είναι συντακτικό σφάλμα. Μετατρέψτε το σε συμβολοσειρά, αποθηκεύστε το, ή περάστε το - αλλά δεν μπορείτε να αναβάλετε την αποτίμησή του.

  • Σταθερό ανά εμφάνιση. Η κλήση της ίδιας υπορουτίνας από δύο διαφορετικά αρχεία δεν αλλάζει το __FILE__ που βλέπει το σώμα της υπορουτίνας· αυτή η τιμή έχει εμπεδωθεί όταν μεταγλωττίστηκε η υπορουτίνα. Αν χρειάζεστε το όνομα αρχείου του καλούντος, χρησιμοποιήστε την caller.

  • Οι οδηγίες #line επανεγγράφουν την τιμή. Σχόλιο της μορφής # line N "NAME" στη στήλη μηδέν επαναφέρει τόσο τον αριθμό γραμμής όσο και (προαιρετικά) το όνομα αρχείου που αναφέρει ο μεταγλωττιστής. Κάθε διακριτικό __FILE__ που μεταγλωττίζεται μετά από μια τέτοια οδηγία υιοθετεί το νέο όνομα. Αυτός είναι ο μηχανισμός που χρησιμοποιούν οι γεννήτριες κώδικα και οι μηχανές προτύπων ώστε τα σφάλματα να δείχνουν στον αρχικό πηγαίο κώδικα .tt / .pod / .xs αντί στον παραγόμενο .pl.

    # line 1 "config.tt"
    my $x = __FILE__;       # "config.tt"
    

    Η πλήρης σύνταξη της οδηγίας προδιαγράφεται στο perlsyn υπό το Plain Old Comments (Not!).

  • Αρθρώματα. Μέσα σε ένα άρθρωμα, το __FILE__ είναι η διαδρομή που χρησιμοποίησε η require για να φορτώσει το αρχείο - συνήθως απόλυτη και κάτω από κάποια ρίζα του @INC. Μην το αναλύετε ως Some/Module.pm· χρησιμοποιήστε dirname(__FILE__) αν χρειάζεστε τον κατάλογο, όχι χειρουργική σε συμβολοσειρά.

  • Ειδικές πηγές γραμμής εντολών. Ο κώδικας από -e αναφέρει -e· ο κώδικας από -E αναφέρει επίσης -e· κώδικας που διοχετεύεται μέσω stdin αναφέρει -. Η string eval χωρίς οδηγία #line αναφέρει (eval N) όπου το N είναι ο μετρητής eval.

  • Η open ενός ορίσματος και ο σωσίας της __FILE__. Δεν υπάρχει handle __FILE__· το διακριτικό δεν έχει καμία σχέση με filehandles. Η open(__FILE__) δεν ανοίγει το τρέχον αρχείο πηγαίου κώδικα - προσπαθεί να ανοίξει αρχείο με όνομα κυριολεκτικά το αναπτυγμένο string του διακριτικού, που σπάνια είναι αυτό που θέλετε.

  • Μη τροποποιήσιμο κατά τον χρόνο εκτέλεσης. Η ανάθεση στο __FILE__ είναι συντακτικό σφάλμα. Ο μηχανισμός για την αλλαγή του τι αναφέρει το __FILE__ είναι η οδηγία #line κατά τη μεταγλώττιση· δεν υπάρχει αντίστοιχο κατά τον χρόνο εκτέλεσης.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • __LINE__ - συνοδευτικό διακριτικό μεταγλώττισης για τον τρέχοντα αριθμό γραμμής· τα δύο χρησιμοποιούνται σχεδόν πάντα μαζί

  • __PACKAGE__ - διακριτικό μεταγλώττισης για το όνομα του τρέχοντος πακέτου, ίδια οικογένεια ειδικών διακριτικών

  • caller - αναζήτηση κατά τον χρόνο εκτέλεσης του ονόματος αρχείου, της γραμμής και του πακέτου του καλούντος· χρησιμοποιήστε την όταν χρειάζεστε τη θέση στον πηγαίο κώδικα του καλούντος αντί της δικής σας

  • die - προσαρτά αυτόματα το at FILE line LINE.· καταφύγετε ρητά στο __FILE__ μόνο όταν καταστέλλετε αυτό το επίθεμα με τελικό newline

  • perlsyn - η ενότητα Plain Old Comments (Not!) προδιαγράφει την οδηγία #line που επανεγγράφει το __FILE__