קלט/פלט · מחלקות ותכנות מונחה־עצמים
dbmclose#
שובר את הקישור בין קובץ DBM להאש שצורף קודם לכן באמצעות dbmopen.
dbmclose הוא בן־הזוג של dbmopen לפירוק. הוא משטיף כל כתיבות תלויות ועומדות, משחרר את המטפלים של ספריית ה־DBM, ומשאיר את HASH כהאש רגיל ולא־קשור שאפשר להמשיך להשתמש בו או להשליך. בקוד מודרני dbmclose הוחלף ברובו על־ידי untie - שניהם משיגים את אותה התוצאה, אך untie עובד לכל משתנה קשור, לא רק להאשים שמקושרים ל־DBM. עדיף untie אלא אם כן אתה מתחזק זוגות dbmopen/dbmclose קיימים ורוצה שהם ייקראו בצורה סימטרית.
תקציר#
dbmclose HASH
dbmclose %hash
מה מקבלים בחזרה#
אמת בהצלחה, שקר בכישלון. אופני כישלון הם נדירים - הנפוץ שבהם הוא העברת האש שמעולם לא נקשר לקובץ DBM מלכתחילה, ובמקרה כזה dbmclose מחזיר שקר וקובע את $!. רוב התוכניות אינן בודקות את ערך ההחזרה; השגיאות המעניינות (דיסק מלא, חריגה ממכסה) צצות בכתיבות שקדמו לסגירה, לא ב־dbmclose עצמו. בדוק אותו כאשר קובץ ה־DBM שוכן על מערכת קבצים שבה כישלון כתיבה דחוי בזמן הסגירה הוא סביר:
dbmclose(%cache)
or warn "dbmclose failed: $!";
מצב גלובלי שהוא נוגע בו#
dbmclose קורא ומשנה את מצב ה־tie של HASH. הוא אינו נוגע באף אחד מהמשתנים המיוחדים הרגילים הקשורים ל־קלט/פלט ($,, $\, $|, מטפל הקובץ הנבחר); גישת DBM אינה זורמת דרך שכבות ה־PerlIO ש־print וחבריו משתמשים בהן. בכישלון, $! נקבע על־ידי ספריית ה־DBM שמתחת.
דוגמאות#
פתיחת קובץ DBM, איטרציה עליו, סגירתו:
dbmopen(%HIST, '/usr/lib/news/history', 0666)
or die "dbmopen: $!";
while (my ($key, $val) = each %HIST) {
print $key, ' = ', unpack('L', $val), "\n";
}
dbmclose(%HIST);
מקבילה באמצעות הזוג המודרני tie/untie - כך צריך להיראות קוד חדש:
use AnyDBM_File;
use Fcntl;
tie(my %HIST, 'AnyDBM_File', '/usr/lib/news/history', O_RDWR, 0666)
or die "tie: $!";
# ... use %HIST ...
untie %HIST;
הגנה מפני סגירת האש לא־קשור:
my %h;
dbmclose(%h)
or warn "not tied to a DBM file: $!"; # warns
שילוב עם בלוק eval כדי לבדל שגיאות ניקוי כלשהן בלי להפיל את הקוד שמסביב:
eval {
dbmclose(%cache) or die "dbmclose: $!";
1;
} or warn $@;
מקרי קצה#
האש שאינו קשור לקובץ DBM: מחזיר שקר, קובע את
$!. אין חריגה הנזרקת. ההאש נשאר ללא שינוי.האש שנקשר באמצעות
tie, לאdbmopen:dbmcloseעדיין עובד ושקול ל־untieעבור אותו האש, מכיוון ש־dbmopenעצמו ממומש כ־tieמתחת למכסה המנוע. ערבוב בין שני ה־APIs חוקי אך מבלבל - בחר אחד לכל האש והישאר עמו.הפניות שעדיין מוחזקות לעצם הקשור: כמו
untie,dbmcloseחותך את הקישור בין ההאש לקובץ ה־DBM, אך אם קוד אחר עדיין מחזיק הפניה לעצם הקשור שמתחת ספריית ה־DBM עלולה שלא לשחרר את המטפלים שלה בפועל עד שאותה הפניה תושלך. הסימפטום הוא קובץ DBM שנשאר נעול או פתוח לאחר קריאתdbmclose. תוכניתuse warningsתקבל את האזהרהuntie attempted while N inner references still existבמקרה כזה.קריאה ל־
dbmcloseפעמיים על אותו האש: הקריאה הראשונה מצליחה, השנייה מחזירה שקר. קוד בסגנון אידמפוטנטי צריך לעקוב אחר האם ההאש קשור כרגע או להתעלם מהכישלון.ההאש נעשה לו
localאו יוצא מהתחום ללאdbmclose: הקישור נשבר באופן מובלע כאשר ההאש מושמד, וספריית ה־DBM סוגרת את הקובץ כחלק מאותו פירוק.dbmcloseמפורש עדיף משום שהוא הופך כישלונות השטפת־כתיבה לגלויים בנקודה ידועה בתוכנית.
הבדלים מ־upstream#
תואם מלא ל־upstream Perl 5.42.
ראו גם#
dbmopen- חצי הפתיחה של הזוג; כלdbmcloseתואם ל־dbmopenקודם על אותו האשuntie- התחליף המודרני והכללי; עובד לכל משתנה קשור, לא רק להאשים שמקושרים ל־DBMtie- בן־הזוג המודרני שלdbmopen, בשימוש עםAnyDBM_File,DB_File,GDBM_File,NDBM_FileאוSDBM_Fileכדי לקשור האש לקובץ DBMclose- לא קשור, אך הפעולה המקבילה למטפלי קובץ: נדרשת כאשר אכפת לך מכישלונות השטפת־כתיבה שצצים בנקודה ידועה