close#
סגירת מטפל קובץ, פליטת המאגרים שלו, ושחרור ה־file descriptor התשתיתי.
close משלים כל קלט/פלט שהיה בהמתנה על FILEHANDLE, מפרק את מחסנית שכבות PerlIO, ומבקש מהקרנל לסגור את ה־descriptor. ערך ההחזרה מבדיל בין סגירה נקייה לבין סגירה שבה כתיבה ממואגרת נכשלה בדרך החוצה, שכבת PerlIO דיווחה על שגיאה, או - עבור pipes - תהליך הילד יצא בערך לא־אפס. ללא ארגומנט, close פועל על מטפל הקובץ הנבחר כעת (ראו select).
תקציר#
close FILEHANDLE
close EXPR
close
מה מקבלים בחזרה#
ערך אמת (1) על סגירה נקייה; שקר אחרת. החזרת שקר משמעה שאחד מהבאים השתבש:
לא ניתן היה לפלוט כתיבה ממואגרת שהייתה בהמתנה (דיסק מלא, pipe שבור, סוקט סגור).
שכבת PerlIO (לדוגמה
:encoding(...),:gzipמשכבת CPAN) דיווחה על שגיאה.שגיאה דביקה קיימת־מראש כבר נרשמה על המטפל.
המטפל הגיע מ־
openעם pipe והילד יצא בערך לא־אפס (או ש־syscall אחר המעורב בפירוק ה־pipe נכשל).
כאשר close מחזיר שקר, $! מחזיק את השגיאה מהפעולה שנכשלה ובטוח לקרוא ממנו. עבור מטפלי pipe, אם הבעיה היחידה הייתה יציאת ילד בערך לא־אפס, $! נקבע ל־0 והסטטוס של הילד מופיע ב־$? (ראו להלן).
תמיד יש לבדוק את ערך ההחזרה במטפלים הניתנים לכתיבה: הבלוק הממוואגר הסופי נפלט בתוך close, כך ש־print שמחזיר אמת קודם לכן אינו מבטיח שהנתונים הגיעו לדיסק.
close $fh
or die "close $path failed: $!";
מצב גלובלי שהוא נוגע בו#
$!- נקבע ל־errnoשנכשל כאשרcloseמחזיר שקר, כולל שגיאת פליטה בכתיבה הממוואגרת הסופית. מאופס ל־0בסגירת pipe שבה הבעיה היחידה הייתה יציאת ילד בערך לא־אפס.$?- עבור מטפלים מ־openעם pipe, נקבע לסטטוס ההמתנה של תהליך הילד: 8 הביטים התחתונים הם האות, 8 הביטים העליונים הם קוד היציאה (אותו קידוד כמוsystem).${^CHILD_ERROR_NATIVE}- עבור מטפלי pipe, נקבע לערך הסטטוס הגולמי של מערכת ההפעלה (לפני הקידוד הנייד של Perl).$.-closeמפורש על מטפל קלט מאפס את מספר השורה הנוכחי. סגירה מרומזת באמצעות פתיחה מחדש של אותו מטפל אינה מאפסת.מטפל הקובץ הנבחר כעת (באמצעות
select) -closeללא ארגומנט סוגר אותו.
דוגמאות#
סגירת קובץ רגיל ובדיקת כישלון פליטה:
open my $fh, ">", "out.txt" or die $!;
print {$fh} @records;
close $fh or die "flush to out.txt failed: $!";
סגירת pipe שנפתח לכתיבה ובחינת סטטוס היציאה של הילד. close ממתין לילד, ואז מאכלס את $?:
open(my $sort, "|-", "sort", ">", "foo")
or die "can't start sort: $!";
# ... print records to $sort ...
close $sort
or warn $! ? "error closing sort pipe: $!"
: "sort exited with status " . ($? >> 8);
סגירת pipe שנפתח לקריאה, ולאחר מכן איסוף סטטוס היציאה של הפקודה. קוד היציאה הוא 8 הביטים העליונים של $?:
open(my $who, "-|", "who") or die $!;
my @lines = <$who>;
close $who;
my $exit = $? >> 8;
close חשוף סוגר את המטפל ש־select הפך לנוכחי לאחרונה, ואז משחזר את STDOUT כמטפל הנבחר:
open my $log, ">>", "app.log" or die $!;
my $old = select $log;
print "entry\n";
close; # closes $log (the selected handle)
select $old;
סגירת קצה הקריאה של pipe מוקדם גורמת לכותב לקבל SIGPIPE. אם לכותב אין מטפל, הוא ייהרג - יש לרוקן את ה־pipe תחילה אם נדרש שהכותב יצא בצורה נקייה:
open my $gen, "-|", "some-producer" or die $!;
while (<$gen>) { last if /^END/ }
1 while <$gen>; # drain so the child finishes cleanly
close $gen or warn "producer failed: $!";
מקרי קצה#
closeחשוף - ללא ארגומנט, סוגר את מטפל הקובץ הנבחר כעת. בתוכנית שהתחילה זה עתה זהוSTDOUT; לאחרselect($fh)זה$fh. לעיתים נדירות זה הרצוי מחוץ לקוד עם תחום הדוק.פתיחה מחדש סוגרת בשבילך -
open my $fh, ...על מטפל שכבר פתוח יסגור תחילה את ה־descriptor הישן. הסגירה המרומזת אינה מאפסת את$.;closeמפורש כן מאפס. יש להשתמש ב־closeמפורש כאשר מצב מספר־השורה חשוב.יציאה מהתחום סוגרת מטפלים לקסיקליים - כאשר ההפניה האחרונה למטפל קובץ לקסיקלי יוצאת מהתחום, Perl סוגר אותו. אם סגירה מרומזת זו נכשלת (שגיאת פליטה, יציאת ילד בערך לא־אפס), Perl פולט אזהרה
Warning: unable to close filehandle %s properly. יש לקרוא ל־closeבמפורש בנקודה שבה ניתן לבדוק את ערך ההחזרה ולהשתיק את האזהרה הזו.מטפלים עקיפים -
FILEHANDLEעשוי להיות כל ביטוי שמפיק מטפל קובץ שמיש: bareword (close STDERR), סקלר (close $fh), הפניה ל־glob (close \*FH), או מטפל מ־autovivification מ־open my $fh, ....סגירת pipe ממתינה - סגירת מטפל pipe חוסמת עד שהילד יוצא, כך ש־
$?מאוכלס עד הזמן ש־closeמחזיר. תחת threads, אם אותו מטפל pipe עדיין פתוח ב־thread אחר,closeמחזיר אמת מיד מבלי לאסוף את הילד.סגירת pipe עם יציאה לא־אפסית -
closeמחזיר שקר וקובע את$!ל־0כך ש־$! ? "$!" : "exit $?"מבחין בין כישלון ברמת מערכת ההפעלה לבין יציאה לא־אפסית רגילה.מטפל סגור או לא תקף - סגירת מטפל שאינו פתוח קובעת את
$!ל־"Bad file descriptor"ומחזירה שקר. תחתuse warnings, נפלטת אזהרהclose() on unopened filehandle.STDIN / STDOUT / STDERR - ניתן לסגור אותם כמו כל מטפל אחר. ה־descriptor משוחרר וייעשה בו שימוש חוזר על־ידי ה־
openהבא על המטפל הסטנדרטי, וכך עובד ההפניה הקלאסיopen STDOUT, ">", "log".
הבדלים מהמקור#
תאימות מלאה עם Perl 5.42 המקורי.
ראו גם#
open- מקבילה;openעל מטפל שכבר פתוח מבצעcloseמרומז תחילה (אך אינו מאפס את$.)print-printהממוואגר הסופי נפלט בתוךclose, כך שההצלחה האמיתית של הכתיבה ידועה רק לאחרclosefileno- מספר ה־descriptor של מטפל; הופך לבלתי תקף לאחר ש־closeמצליחbinmode- מחסנית השכבות שנקבעה על־ידיbinmodeמפורקת במהלךclose, והפירוק שלה עצמו עלול להיכשל$?- סטטוס יציאת הילד המאוכלס על־ידיcloseעל מטפל pipe$!- שגיאה מפעולת ה־close שנכשלה