I/O

write#

Αποδίδει μία εγγραφή σε ένα filehandle μέσω της συσχετισμένης format του.

Η write είναι το εκτελεστικό μισό του μηχανισμού παραγωγής αναφορών της Perl: παίρνει την εικόνα που δηλώνει μια format, τοποθετεί τις τιμές από τις αντίστοιχες γραμμές ορισμάτων στα πεδία, και εκπέμπει τις προκύπτουσες γραμμές στο FILEHANDLE. Παρακολουθεί επίσης τη σελίδα: όταν δεν απομένουν αρκετές γραμμές, γράφει ένα form feed, εκτελεί τη μορφή κορυφής σελίδας, και κατόπιν γράφει την εγγραφή. Η write είναι ο μόνος τρόπος με τον οποίο μια δηλωμένη format παράγει έξοδο· μια format είναι αδρανής μέχρι να την αναφέρει η write.

Μη μπερδεύετε αυτό με τη syswrite ή με το αντίστροφο της read: η write είναι αυστηρά ο εκτελεστής εγγραφών εικόνας. Δεν έχει καμία σχέση με ωμή έξοδο bytes.

Σύνοψη#

write FILEHANDLE
write EXPR
write

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

1 σε επιτυχία, undef σε αποτυχία (με το $! ορισμένο). Μια αποτυχία εδώ είναι τυπικά είτε κλειστό handle είτε σφάλμα I/O στην υποκείμενη εγγραφή - όχι «format not found», το οποίο εκπέμπει croak αντί να επιστρέψει undef.

Πώς η write επιλέγει τη format#

Κάθε filehandle έχει δύο θέσεις format: τη format εγγραφής και τη format κορυφής σελίδας. Εξ ορισμού:

  • Η format εγγραφής είναι η format της οποίας το όνομα ταιριάζει με το filehandle (format STDOUT για το STDOUT, format REPORT για handle που ανοίχτηκε ως REPORT).

  • Η format κορυφής σελίδας είναι το όνομα του filehandle με προσαρτημένο _TOP (STDOUT_TOP, REPORT_TOP), με εφεδρική επιλογή το top στο τρέχον πακέτο.

Και τα δύο είναι ανά handle υπερκαλύψιμα μέσω των $~ (όνομα τρέχουσας format) και $^ (όνομα τρέχουσας format κορυφής σελίδας). Αυτές οι μεταβλητές δρουν στο τρέχον επιλεγμένο handle, οπότε η αλλαγή τους για οτιδήποτε εκτός του STDOUT απαιτεί έναν χορό select:

my $ofh = select REPORT;
$~ = "My_Format";
$^ = "My_Top";
select $ofh;

Αν το FILEHANDLE παραλειφθεί, η write στοχεύει το τρέχον επιλεγμένο handle (προεπιλογή STDOUT). Αν το όρισμα είναι EXPR αντί για bareword, η έκφραση αξιολογείται και η τιμή της συμβολοσειράς αναζητείται ως όνομα filehandle κατά τον χρόνο εκτέλεσης.

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

Η write διαβάζει και ενημερώνει μια συστάδα μεταβλητών format ανά handle. Όλες είναι ανά filehandle, προσπελάσιμες μέσω select:

  • $~ - όνομα της format εγγραφής για το επιλεγμένο handle. Διαβάζεται σε κάθε κλήση write.

  • $^ - όνομα της format κορυφής σελίδας. Λαμβάνεται υπόψη όταν αρχίζει νέα σελίδα.

  • $= - μήκος σελίδας σε γραμμές. Προεπιλογή 60.

  • $- - γραμμές που απομένουν στην τρέχουσα σελίδα. Μειώνεται με κάθε write. Ορίστε σε 0 για να εξαναγκάσετε αλλαγή σελίδας στην επόμενη κλήση.

  • $% - τρέχων αριθμός σελίδας. Αυξάνεται σε κάθε top-of-page.

  • $^L - συμβολοσειρά που εκπέμπεται πριν από κάθε top-of-page εκτός της πρώτης. Προεπιλογή "\f" (form feed).

  • $: - χαρακτήρες πάνω στους οποίους μπορούν να σπάνε τα πεδία λειτουργίας γεμίσματος (^).

  • $^A - ο συσσωρευτής format, ο ενταμιευτής στον οποίο γράφει η formline και τον οποίο εκκενώνει η write. Σπάνια αγγίζεται απευθείας εκτός αν παρακάμπτετε τη write με formline.

Η write επίσης γράφει μέσω της στοίβας PerlIO του handle-στόχου, οπότε το $| (autoflush στο επιλεγμένο handle) εξακολουθεί να ισχύει.

Επεξεργασία top-of-form#

Πριν εκπέμψει την εγγραφή, η write ελέγχει αν η εγγραφή χωράει στις γραμμές που απομένουν στη σελίδα ($-). Αν δεν χωράει:

  1. Εκπέμπει $^L (form feed εξ ορισμού) - παραλείπεται στην πρώτη σελίδα.

  2. Εκτελεί τη format κορυφής σελίδας που ονοματίζει το $^ για την παραγωγή της κεφαλίδας σελίδας.

  3. Επανατοποθετεί το $- σε $= και αυξάνει το $%.

  4. Εκπέμπει την εγγραφή.

Στην πρώτη write σε ένα handle, το βήμα 1 παραλείπεται ώστε η έξοδος να μην ξεκινά με form feed.

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

Βασική αναφορά με κεφαλίδα:

format STDOUT_TOP =
                        Passwd File
 Name                Login    Office   Uid   Gid Home
 ------------------------------------------------------------------
.
format STDOUT =
 @<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<
 $name,              $login,  $office,$uid,$gid, $home
.

while (my @row = getpwent) {
    ($name, $login, $uid, $gid, $office, $home) = @row[0,0,2,3,5,7];
    write;
}

Εγγραφή σε ονοματισμένο filehandle. Το όνομα format εξ ορισμού είναι το όνομα του handle· δεν χρειάζεται select αν η προεπιλογή είναι αποδεκτή:

open my $fh, ">", "report.txt" or die $!;
format REPORT =
 @<<<<<<<<<<<<<<   @>>>>>>>
 $item,            $count
.
# rebind the glob so REPORT refers to $fh
*REPORT = *$fh;
for my $r (@records) {
    ($item, $count) = @$r;
    write REPORT;
}
close $fh;

Εναλλαγή format κατά τον χρόνο εκτέλεσης ορίζοντας το $~ στο επιλεγμένο handle. Το local περιορίζει την αλλαγή στην τρέχουσα εμβέλεια:

sub print_summary {
    local $~ = "SUMMARY_FORMAT";
    write;
}

Εξαναγκασμός αλλαγής σελίδας μηδενίζοντας το $- πριν την επόμενη κλήση:

$- = 0;                  # next write starts a new page
write;

Η write EXPR επιλέγει το handle κατά τον χρόνο εκτέλεσης από συμβολοσειρά - χρήσιμο όταν ο στόχος καθορίζεται από δεδομένα:

my $handle_name = $verbose ? "LOG" : "STDOUT";
write $handle_name;

Εναλλαγή print με write: νόμιμη, αλλά το $- παρακολουθεί μόνο την έξοδο της write. Αν μια ριπή print καταναλώσει γραμμές σελίδας που σας ενδιαφέρουν, μειώστε χειροκίνητα το $-:

print "extra note: $msg\n";
$-  -= 1;                 # keep the page counter honest
write;

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

  • Format δεν βρέθηκε: αν η format που ονοματίζει το $~ δεν υπάρχει, η write κάνει croak με Undefined format "NAME" called. Αυτό είναι μοιραίο σφάλμα, όχι αποτυχία τύπου επιστροφή-undef-με-$!.

  • Κλειστό filehandle: επιστρέφει undef και ορίζει το $!. Υπό το use warnings εκπέμπεται προειδοποίηση write() on closed filehandle.

  • Εγγραφή ψηλότερη από σελίδα: αν η ίδια η εγγραφή έχει περισσότερες γραμμές από το $=, η write εξακολουθεί να εκπέμπει όλες τις γραμμές της σε μία σελίδα - δεν χωρίζει μια μεμονωμένη εγγραφή ανάμεσα σε όρια σελίδας. Το υπερμέγεθος γίνεται ανεκτό σιωπηρά.

  • Εφεδρική επιλογή _TOP: αν δεν υπάρχει format <HANDLE>_TOP, η write καταφεύγει στη format με όνομα top στο τρέχον πακέτο. Αυτό σπάνια είναι αυτό που θέλετε για αυτο-δημιουργημένα handles· ορίστε ρητά το $^ όταν έχει σημασία.

  • Λεξιλογικές μεταβλητές σε formats: οι μεταβλητές my που δηλώνονται έξω από μια format δεν είναι ορατές μέσα της εκτός αν η format δηλωθεί εντός της λεξιλογικής εμβέλειας αυτών των μεταβλητών. Αυτό τσιμπάει όποιον τυλίγει τη write μέσα σε υπορουτίνα και απορεί γιατί η αναφορά είναι κενή - μετακινήστε τη δήλωση format μέσα στην υπορουτίνα, ή χρησιμοποιήστε καθολικές πακέτου για τις εκφράσεις της γραμμής ορισμάτων.

  • Η top-of-page ενεργοποιείται μεταξύ εγγραφών, όχι μέσα σε σελίδα: η write ελέγχει τον χώρο στη σελίδα μία φορά ανά εγγραφή. Μια εγγραφή που ξεκινά κοντά στο κάτω μέρος της σελίδας είτε θα χωρέσει πλήρως είτε θα ενεργοποιήσει top-of-page πριν γραφεί· δεν διασταυρώνει ποτέ.

  • LC_NUMERIC και αριθμητικά πεδία: αν το use locale ισχύει όταν δηλώνεται η format, η υποδιαστολή στα αριθμητικά πεδία ακολουθεί το locale κατά τη στιγμή δήλωσης - όχι κατά τη στιγμή της write. Η αλλαγή locale μετά τη μεταγλώττιση της format δεν αλλάζει τον διαχωριστή.

  • Οι χαρακτήρες ελέγχου σε πεδία κειμένου αντικαθίστανται με κενά ώστε να μη μπορούν να ανακατέψουν τη στοίχιση στηλών. Η μόνη εξαίρεση είναι ο \r σε πεδία λειτουργίας γεμίσματος, όπου εξαναγκάζει αλλαγή γραμμής.

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

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

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

  • format - δηλώνει την εικόνα που αποδίδει η write· τα δύο είναι ανούσια το ένα χωρίς το άλλο

  • formline - εκτελεί μία γραμμή εικόνας έναντι λίστας ορισμάτων μέσα στο $^A χωρίς παρακολούθηση σελίδας· η χαμηλού επιπέδου πρωτογενής συνάρτηση πίσω από τη write

  • select - αλλάζει ποιο handle στοχεύει η write όταν καλείται χωρίς όρισμα, και είναι προαπαιτούμενο για τον ορισμό οποιουδήποτε από τα $~, $^, $=, $- ανά handle

  • print - έξοδος ελεύθερης μορφής όταν η αναφορά σε στήλες είναι υπερβολή· μπορεί να εναλλάσσεται με write στο ίδιο handle

  • $~ - υπερκαλύπτει το όνομα της format εγγραφής για το επιλεγμένο handle

  • $- - γραμμές που απομένουν στην τρέχουσα σελίδα· ορίστε σε 0 για να εξαναγκάσετε νέα σελίδα πριν την επόμενη write

  • perlform.pod - πλήρης γραμματική γραμμών εικόνας, κανόνες λειτουργίας γεμίσματος, και επεξεργασμένα παραδείγματα αναφορών