eof#
בודק מטפל קובץ עבור סוף־קובץ.
eof מדווח האם הקריאה הבאה על מטפל קובץ תחזיר סוף־קובץ. שלוש צורות הקריאה נראות דומות אך משמעותן שונה: eof FILEHANDLE שואל על מטפל ספציפי, eof חשוף שואל על המטפל שממנו קראו לאחרונה, ו־eof() עם סוגריים ריקים שואל על זרם ARGV הווירטואלי המוזן על־ידי <>. הצורות אינן ניתנות להחלפה - בחירת הצורה הלא־נכונה היא הבאג הקלאסי של built-in זה.
תקציר#
eof FILEHANDLE
eof()
eof
מה מקבלים בחזרה#
1 אם הקריאה הבאה על המטפל תחזיר סוף־קובץ, או אם המטפל אינו פתוח. 0 אחרת. eof לעולם אינו חוסם בהמתנה לקלט נוסף בקובץ רגיל, אך ב־pipe או טרמינל הוא עשוי לקרוא ולהחזיר תו אחד כדי להחליט - ראה מקרי קצה.
מצב גלובלי שהוא נוגע בו#
ARGV- מטפל הקובץ הקסום העומד מאחורי האופרטור<>.eof()בוחן ועשוי לקדם אותו;eofבתוך לולאתwhile (<>)מתשאל אותו בעקיפין.@ARGV- רשימת שמות הקבצים ש־<>עובר עליהם.eof()שנקרא לפני שנעשה שימוש ב־<>מפעיל בחינה של@ARGV, ואם ריק, מארגן אתSTDINלהיקרא.$.- מספר שורת הקלט הנוכחית, מצורף למטפל ש־eofמתשאל. אינו נכתב על־ידיeofעצמו, אך רלוונטי באידיומים שלהלן שבהםclose ARGVמאפס אותו בגבולות הקובץ.
שלוש הצורות, מפורטות#
eof FILEHANDLE - שואל על המטפל הזה האחד. FILEHANDLE יכול להיות bareword, סקלר המחזיק מטפל, או ביטוי המוערך לאחד. מחזיר אמת עבור מטפל סגור או שמעולם לא נפתח.
eof (ללא סוגריים, ללא ארגומנט) - שואל על הקובץ האחרון שנקרא. בתוך לולאת while (<>) { ... } משמעו ״קובץ ה־ARGV הנוכחי״ - הקובץ הפיזי המוזרם כעת, לא כל רצף ה־<>. eof הופך לאמת בכל גבול קובץ, פעם אחת לכל קובץ קלט.
eof() (סוגריים ריקים) - שואל על זרם ה־<> בכללותו. הוא הופך לאמת רק בסוף הקובץ האחרון ב־@ARGV. אם <> עוד לא נעשה בו שימוש, eof() יבחן את @ARGV, יחזור ל־STDIN כאשר @ARGV ריק, ועשוי למעשה לפתוח את הקובץ הראשון כדי לענות על השאלה.
eof חשוף ו־eof() נראים כמעט זהים ועושים דברים שונים לגמרי. הסוגריים חשובים.
דוגמאות#
בדוק מטפל ספציפי לפני הקריאה הבאה:
open my $fh, "<", "data.txt" or die $!;
while (not eof $fh) {
my $line = <$fh>;
# process $line
}
close $fh;
האידיום הקלאסי while (<>), איפוס $. בכל גבול קובץ. eof חשוף (ללא סוגריים) הוא מה שאתה רוצה כאן - הוא מופעל פעם לכל קובץ קלט:
while (<>) {
next if /^\s*#/;
print "$.\t$_";
} continue {
close ARGV if eof; # not eof() - resets $. per file
}
הוסף סמן לפני השורה האחרונה של הקובץ האחרון. eof() עם סוגריים תופס את סוף כל זרם ה־<>, לא של כל קובץ:
while (<>) {
if (eof()) {
print "--------------\n";
}
print;
last if eof(); # needed when reading from a terminal
}
התגונן מפני מטפל סגור. eof על מטפל סגור או שמעולם לא נפתח מחזיר אמת ללא אזהרה:
my $fh; # never opened
if (eof $fh) {
warn "handle not ready";
}
מקרי קצה#
eofלפני כל קריאה מחזיר שקר, לא אמת. ל־eofחשוף ללא קריאה קודמת אין ״קובץ אחרון שנקרא״ להתייחס אליו ו־Perl מתייחס אליו כשקר. כתיבתif (eof) { ... }בראש תוכנית אינה אומרת ״אם אין קלט״ - השתמש ב־eof()לכך.ל־
eof()לפני שנעשה שימוש ב־<>יש תופעות לוואי. הוא בוחן את@ARGV, ואם@ARGVריק הוא מארגן ש־<>יקרא מ־STDIN.eof()תועה בתחילת התוכנית יכול לפיכך לקשור בשקט את התוכנית ל־STDIN.eof()לאחר ש־<>מיצה את הקלט שלו מניח שאתה מתחיל מעבר@ARGVנוסף. אם@ARGVריק בנקודה זו, ה־<>הבא קורא מ־STDIN. בדרך כלל זה לא מה שאתה רוצה; קבע את@ARGVבמפורש או בדוק את צורתeofהחשוף במקום.eofבטרמינל צורך תו. המימוש קורא בית אחד ומבצעungetcכדי לדעת האם קיים קלט נוסף. בטרמינלים ההחזרה עשויה שלא לשרוד לאחר שהושג סוף־קובץ - אל תקראeof FHבטרמינל לאחר שכבר הגעת לשם ל־EOF, או שהמטפל יכול לאבד את תנאי סוף־הקובץ שלו.מטפל סגור או שמעולם לא נפתח -
eof FILEHANDLEמחזיר אמת. אין דרך להבחין בין ״סגור״ ל־״ב־EOF״ באמצעותeofלבד; בדוקfilenoאו עקוב אחר מצב הפתיחה בעצמך אם זה משנה.eof(ARGV)שווה ל־eofחשוף בתוךwhile (<>). שניהם מתשאלים את קובץ ה־ARGVהנוכחי. העדףeofחשוף לקיצור וכדי להבחין ויזואלית בצורתeof()הסוגרת.אתה לעיתים נדירות זקוק ל־
eofבכלל. אופרטורי הקלט מחזיריםundefבסוף־קובץ, כך ש־while (my $line = <$fh>) { ... }ו־while (<>) { ... }מטפלים בסיום ללא כל בדיקתeof. פנה ל־eofרק כאשר אתה צריך לפעול בגבול - שורה אחרונה, איפוס פר־קובץ, סמן קובץ אחרון.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.