LINE#
Ένα διακριτικό μεταγλώττισης που αποτιμάται στον αριθμό γραμμής στην οποία εμφανίζεται μέσα στον πηγαίο κώδικα.
Το __LINE__ δεν είναι συνάρτηση. Είναι ένα ειδικό διακριτικό που ο αναλυτής αντικαθιστά, κατά τη μεταγλώττιση, με έναν κυριολεκτικό ακέραιο - τον αριθμό γραμμής της θέσης στο αρχείο όπου βρίσκεται το διακριτικό. Είναι ο τυπικός τρόπος για να σφραγίσετε ένα διαγνωστικό, μια γραμμή καταγραφής ή μια εκτύπωση αποσφαλμάτωσης με την ακριβή θέση που την παρήγαγε, χωρίς το κόστος μιας αναζήτησης caller κατά τον χρόνο εκτέλεσης.
Σύνοψη#
__LINE__
Τι επιστρέφεται#
Ένας ακέραιος: ο αριθμός γραμμής του διακριτικού, με αρίθμηση από το 1, μέσα στην τρέχουσα μονάδα μεταγλώττισης. Η τιμή είναι ένας απλός αριθμός, χρησιμοποιήσιμος οπουδήποτε δέχεται αριθμό - σε αριθμητικές πράξεις, σε παρεμβολή σε συμβολοσειρά, ως κλειδί πίνακα κατακερματισμού, ως όρισμα σε die ή warn.
print __LINE__, "\n"; # prints the line number of this line
my $where = "line " . __LINE__;
Επειδή η αντικατάσταση γίνεται κατά την ανάλυση, κάθε εμφάνιση του __LINE__ είναι ουσιαστικά μια διαφορετική σταθερά. Δύο αντίγραφα σε δύο διαφορετικές γραμμές παράγουν δύο διαφορετικούς αριθμούς· ένα μεμονωμένο __LINE__ μέσα σε βρόχο παράγει τον ίδιο αριθμό σε κάθε επανάληψη.
Κατά τη μεταγλώττιση, όχι κατά τον χρόνο εκτέλεσης#
Η τιμή παγώνει όταν μεταγλωττίζεται ο πηγαίος κώδικας. Μια συνηθισμένη παρανόηση:
sub where { return __LINE__ } # returns the line where `__LINE__`
# was written, i.e. the `sub` body's
# line - NOT the caller's line
Για να αποτυπώσετε τον αριθμό γραμμής του καλούντος, χρησιμοποιήστε την caller:
sub where { my (undef, undef, $line) = caller; return $line }
Μέσα σε eval συμβολοσειράς, το __LINE__ αριθμεί τις γραμμές της συμβολοσειράς που μεταγλωττίζεται (ξεκινώντας από 1 για την πρώτη γραμμή της συμβολοσειράς), όχι τις γραμμές του περιβάλλοντος αρχείου.
Αλλαγή του αναφερόμενου αριθμού γραμμής#
Ο αριθμός γραμμής που αναφέρει το __LINE__ είναι ο αριθμός γραμμής στον οποίο ο λεκτικός αναλυτής πιστεύει ότι βρίσκεται. Μια οδηγία #line επαναφέρει αυτή την πεποίθηση:
#line 1000 "virtual.pl"
print __LINE__, "\n"; # prints 1001
Το #line NNN από μόνο του ρυθμίζει μόνο τον αριθμό γραμμής· το #line NNN "NAME" αλλάζει επίσης ό,τι αναφέρει το __FILE__. Γεννήτριες κώδικα, μηχανές προτύπων και προεπεξεργαστές το χρησιμοποιούν για να κάνουν τα διαγνωστικά να δείχνουν πίσω στον αρχικό πηγαίο κώδικα αντί στο παραγόμενο αρχείο. Δείτε το Plain Old Comments (Not!) στην ενότητα perlsyn της αναφοράς για την ακριβή σύνταξη και τους κανόνες εμβέλειας.
Παραδείγματα#
Σφραγίστε ένα διαγνωστικό με την προέλευσή του:
die "bad input at ", __FILE__, " line ", __LINE__, "\n"
unless defined $x;
Η die με μήνυμα που δεν τελειώνει σε newline προσαρτά ήδη " at FILE line LINE.\n". Χρησιμοποιήστε την παραπάνω ρητή μορφή μόνο όταν θέλετε να ελέγξετε τη μορφοποίηση, ή όταν έχετε καταστείλει το αυτόματο επίθημα με ένα τελικό newline.
Καταγραφή με πρόθεμα αρχείου και γραμμής:
sub logf {
my ($file, $line) = (__FILE__, __LINE__);
warn "[$file:$line] @_\n";
}
Αυτό καταγράφει τη γραμμή όπου γράφτηκε το __LINE__ - μέσα στην logf - κάτι που σπάνια είναι αυτό που θέλετε. Το σωστό μοτίβο χρησιμοποιεί την caller:
sub logf {
my (undef, $file, $line) = caller;
warn "[$file:$line] @_\n";
}
Χρησιμοποιήστε το __LINE__ απευθείας όταν σημειώνετε αυτό το κομμάτι κώδικα, όχι τον καλούντα:
print STDERR "checkpoint at line ", __LINE__, "\n";
Μετατοπίστε τα διαγνωστικά με #line:
#line 42 "user-input.pl"
die "syntax error\n"; # dies reporting user-input.pl line 42
Οριακές περιπτώσεις#
Δεν είναι συνάρτηση, δεν καλείται. Το
__LINE__()είναι συντακτικό σφάλμα. Το διακριτικό δεν δέχεται ορίσματα και δεν έχει μορφή με παρενθέσεις.Δεν παρεμβάλλεται μέσα σε συμβολοσειρές σε διπλά εισαγωγικά. Το
"see line __LINE__"εκτυπώνει την κυριολεκτική συμβολοσειράsee line __LINE__. Συνενώστε αντ’ αυτού:"see line " . __LINE__.Δεν είναι έγκυρο bareword κλειδιού πίνακα κατακερματισμού στη συνηθισμένη σύντομη μορφή. Μέσα σε περιβάλλον κλειδιού πίνακα κατακερματισμού
{ ... }, το$h{__LINE__}λειτουργεί επειδή το διακριτικό αναλύεται ως έκφραση, αλλά και το$h{ __LINE__ }λειτουργεί και είναι σαφέστερο. Το$h{__LINE__ => 1}αναλύει το__LINE__ως bareword παχιού κόμματος (δηλαδή τη συμβολοσειρά"__LINE__"), κάτι που σχεδόν ποτέ δεν είναι αυτό που θέλετε - γράψτε(__LINE__, 1)ή(__LINE__() => 1)αν θέλετε την κυριολεκτική τιμή.Μέσα σε
evalσυμβολοσειράς, το__LINE__μετράει από τη γραμμή 1 της αποτιμημένης συμβολοσειράς. Προθέστε τη δική σας οδηγία#lineστη συμβολοσειρά για να κάνετε τα διαγνωστικά να δείχνουν στο περικλείον αρχείο:my $code = qq{#line @{[__LINE__+1]} "@{[__FILE__]}"\n} . $user_code; eval $code;
Μέσα στο σώμα ενός here-doc, το
__LINE__αποτιμάται στη γραμμή του ανοίγματος<<στη γραμμή όπου αναφέρεται το here-doc, όχι σε γραμμές μέσα στο σώμα - τα σώματα here-doc είναι δεδομένα, όχι κώδικας.Heredoc και οδηγίες γραμμής. Το
#lineμέσα σε σώμα here-doc δεν έχει καμία επίδραση· είναι απλώς κείμενο. Το#lineλειτουργεί μόνο ως οδηγία στην αρχή γραμμής, σε περιβάλλον κώδικα.Αρνητικοί ή μηδενικοί αριθμοί γραμμής. Το
#line 0είναι νόμιμο και κάνει την επόμενη φυσική γραμμή να αναφέρεται ως γραμμή 1 (η ίδια η οδηγία είναι γραμμή 0, η γραμμή μετά είναι γραμμή 1). Οι αρνητικοί αριθμοί γίνονται δεκτοί αλλά παράγουν εκπληκτικά διαγνωστικά· μην το κάνετε.
Διαφορές από το upstream#
Πλήρως συμβατό με το upstream Perl 5.42.
Δείτε επίσης#
__FILE__- το συνοδευτικό διακριτικό για το όνομα του τρέχοντος αρχείου πηγαίου κώδικα· τα δύο σχεδόν πάντα χρησιμοποιούνται μαζί__PACKAGE__- διακριτικό μεταγλώττισης για το όνομα του τρέχοντος πακέτου, ίδια οικογένεια ειδικών διακριτικώνcaller- το ισοδύναμο χρόνου εκτέλεσης όταν χρειάζεστε τον αριθμό γραμμής του καλούντος, όχι τη γραμμή του ίδιου του σημείου κλήσηςdie- προσαρτά αυτόματαat FILE line LINEόταν το μήνυμα δεν έχει τελικό newline, καταργώντας την ανάγκη για ρητό__LINE__warn- ίδια αυτόματη συμπεριφορά εντοπισμού θέσης με τηνdieγια μη μοιραία διαγνωστικά