קלט/פלט · מחלקות ותכנות מונחה־עצמים

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 - התחליף המודרני והכללי; עובד לכל משתנה קשור, לא רק להאשים שמקושרים ל־DBM

  • tie - בן־הזוג המודרני של dbmopen, בשימוש עם AnyDBM_File, DB_File, GDBM_File, NDBM_File או SDBM_File כדי לקשור האש לקובץ DBM

  • close - לא קשור, אך הפעולה המקבילה למטפלי קובץ: נדרשת כאשר אכפת לך מכישלונות השטפת־כתיבה שצצים בנקודה ידועה