קלט/פלט

write#

מציג רשומה אחת למטפל קובץ דרך ה־format המשויך לו.

write הוא חצי הביצוע של מנגנון יצירת הדו״חות של Perl: הוא לוקח את התמונה המוצהרת על ידי format, שותל את הערכים משורות הארגומנטים התואמות לתוך השדות, ומנפיק את השורות המתקבלות ל־FILEHANDLE. הוא גם עוקב אחר העמוד: כאשר אין מספיק שורות שנותרו, הוא כותב form feed, מריץ את format ראש העמוד, ואז כותב את הרשומה. write הוא הדרך היחידה ש־format מוצהר מייצרת פלט; format הוא רדום עד ש־write מתייחס אליו.

אסור לבלבל עם syswrite או עם ההיפוך של read: write הוא בהחלט המבצע של רשומת התמונה. אין לו שום קשר לפלט בייטים גולמי.

תקציר#

write FILEHANDLE
write EXPR
write

מה מקבלים בחזרה#

1 בהצלחה, undef בכשל (כאשר $! מוגדר). כשל כאן הוא בדרך כלל או מטפל סגור או שגיאת קלט/פלט בכתיבה הבסיסית - לא ”format לא נמצא“, שזורק במקום להחזיר undef.

איך write בוחר את ה־format#

לכל מטפל קובץ יש שתי משבצות format: format הרשומה ו־format ראש העמוד. בברירת מחדל:

  • format הרשומה הוא ה־format ששמו תואם למטפל הקובץ (format STDOUT עבור STDOUT, format REPORT עבור מטפל הפתוח כ־REPORT).

  • format ראש העמוד הוא שם מטפל הקובץ עם _TOP מצורף (STDOUT_TOP, REPORT_TOP), עם נפילה ל־top בחבילה הנוכחית.

את שניהם ניתן לדרוס לכל מטפל דרך $~ (שם ה־format הנוכחי) ו־$^ (שם format ראש העמוד הנוכחי). משתנים אלה פועלים על המטפל הנבחר הנוכחי, כך ששינויים עבור כל דבר מלבד STDOUT דורש ריקוד select:

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

אם FILEHANDLE מושמט, write מכוון למטפל הנבחר הנוכחי (ברירת מחדל STDOUT). אם הארגומנט הוא EXPR במקום bareword, הביטוי מוערך וערך המחרוזת שלו נחפש כשם מטפל הקובץ בזמן ריצה.

מצב גלובלי שהוא נוגע בו#

write קורא ומעדכן אשכול של משתני format לכל מטפל. כולם לכל מטפל קובץ, נגישים דרך select:

  • $~ - שם format הרשומה עבור המטפל הנבחר. נקרא בכל קריאת write.

  • $^ - שם format ראש העמוד. נועצים בו כשעמוד חדש מתחיל.

  • $= - אורך עמוד בשורות. ברירת מחדל 60.

  • $- - שורות שנותרו בעמוד הנוכחי. מוקטן על ידי כל write. יש להגדיר ל־0 כדי לכפות שבירת עמוד בקריאה הבאה.

  • $% - מספר העמוד הנוכחי. מוגדל בכל ראש עמוד.

  • $^L - מחרוזת המונפקת לפני כל ראש עמוד למעט הראשון. ברירת מחדל "\f" (form feed).

  • $: - תווים שעליהם שדות מצב מילוי (^) רשאים לשבור.

  • $^A - צובר ה־format, ה־buffer ש־formline כותב לתוכו ו־write מבצע flush עליו. נגעים בו ישירות לעיתים נדירות אלא אם עוקפים את write עם formline.

write גם כותב דרך מחסנית ה־PerlIO של מטפל היעד, כך ש־$| (autoflush על המטפל הנבחר) עדיין חל.

עיבוד ראש־טופס#

לפני הנפקת הרשומה, write בודק אם הרשומה נכנסת בשורות שנותרו בעמוד ($-). אם לא:

  1. מנפיק את $^L (form feed בברירת מחדל) - מדולג בעמוד הראשון ממש.

  2. מריץ את format ראש העמוד ששמו ב־$^ כדי לייצר את כותרת העמוד.

  3. מאפס את $- ל־$= ומגדיל את $%.

  4. מנפיק את הרשומה.

ב־write הראשון ממש למטפל, צעד 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;
}

כתיבה למטפל קובץ בעל שם. שם ה־format בברירת מחדל הוא שם המטפל; אין צורך ב־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 בזמן ריצה על ידי הגדרת $~ על המטפל הנבחר. local תוחם את השינוי לתיחום הנוכחי:

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

כפיית שבירת עמוד על ידי אפסון $- לפני הקריאה הבאה:

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

write EXPR בוחר את המטפל בזמן ריצה ממחרוזת - שימושי כשהיעד מונע נתונים:

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 זורק עם Undefined format "NAME" called. זוהי שגיאה קטלנית, לא כשל שמחזיר undef עם $!.

  • מטפל קובץ סגור: מחזיר undef ומגדיר את $!. תחת use warnings מונפקת אזהרת write() on closed filehandle.

  • רשומה גבוהה מעמוד: אם לרשומה עצמה יש יותר שורות מ־$=, write עדיין מנפיק את כל שורותיה בעמוד אחד - הוא אינו מפצל רשומה יחידה לרוחב גבול עמוד. הגודל היתר נסבל בשקט.

  • Fallback של _TOP: אם אין format <HANDLE>_TOP, write נופל ל־format ששמו top בחבילה הנוכחית. זה לעיתים נדירות מה שרוצים עבור מטפלים מאוטוויפים; יש להגדיר $^ במפורש כשזה משנה.

  • משתנים לקסיקליים ב־formats: משתני my המוצהרים מחוץ ל־format אינם נראים בתוכו אלא אם ה־format מוצהר בתוך התיחום הלקסיקלי של אותם משתנים. זה נושך את מי שעוטף write בתוך תת־שגרה ותוהה למה הדו״ח ריק - יש להעביר את הצהרת ה־format לתוך התת־שגרה, או להשתמש בגלובלי חבילה עבור ביטויי שורת הארגומנטים.

  • ראש עמוד מופעל באמצע־רשומה, לא באמצע־עמוד: write בודק מקום בעמוד פעם אחת לכל רשומה. רשומה שמתחילה ליד תחתית העמוד או תיכנס במלואה או תפעיל ראש עמוד לפני שתיכתב; היא לעולם אינה חוצה.

  • LC_NUMERIC ושדות מספריים: אם use locale בתוקף כש־format מוצהר, הנקודה העשרונית בשדות מספריים עוקבת אחר ה־locale בזמן ההצהרה - לא בזמן write. החלפת locales אחרי שה־format מהודר אינה משנה את המפריד.

  • תווי בקרה בשדות טקסט מוחלפים ברווחים כך שאינם יכולים לערבב את יישור העמודות. החריג היחיד הוא \r בשדות מצב מילוי, שם הוא כופה שבירת שורה.

הבדלים מהמקור#

תואם במלואו ל־Perl 5.42 במקור.

ראו גם#

  • format - מצהיר על התמונה ש־write מציג; השניים חסרי משמעות בלי זה את זה

  • formline - מריץ שורת תמונה אחת מול רשימת ארגומנטים לתוך $^A ללא שום מעקב עמוד; הפרימיטיב ברמה נמוכה שמאחורי write

  • select - משנה לאיזה מטפל write מכוון כשנקרא ללא ארגומנט, ותנאי מוקדם להגדרת כל אחד מ־$~, $^, $=, $- לכל מטפל

  • print - פלט בצורה חופשית כשדיווח עמודות הוא יתר על המידה; ניתן לשלב עם write על אותו מטפל

  • $~ - דורס את שם format הרשומה עבור המטפל הנבחר

  • $- - שורות שנותרו בעמוד הנוכחי; יש להגדיר ל־0 כדי לכפות עמוד חדש לפני ה־write הבא

  • perlform.pod - דקדוק מלא של שורות תמונה, כללי מצב מילוי, ודוגמאות דו״ח מפורטות