I/O · Κλάσεις και αντικειμενοστρέφεια

dbmclose#

Διακόπτει τη δέσμευση μεταξύ ενός αρχείου DBM και ενός hash που είχε προηγουμένως προσαρτηθεί με dbmopen.

Η dbmclose είναι το αντίστοιχο αποδόμησης της dbmopen. Εκκενώνει τυχόν εκκρεμείς εγγραφές, απελευθερώνει τα handles της βιβλιοθήκης DBM και αφήνει το HASH ως ένα συνηθισμένο, μη tied hash που μπορείτε να συνεχίσετε να χρησιμοποιείτε ή να απορρίψετε. Σε σύγχρονο κώδικα η dbmclose έχει σε μεγάλο βαθμό αντικατασταθεί από την untie - οι δύο επιτυγχάνουν το ίδιο πράγμα, αλλά η untie λειτουργεί για κάθε tied μεταβλητή, όχι μόνο για hashes δεσμευμένα σε DBM. Προτιμήστε την untie εκτός αν συντηρείτε υπάρχοντα ζεύγη dbmopen/dbmclose και θέλετε να διαβάζονται συμμετρικά.

Σύνοψη#

dbmclose HASH
dbmclose %hash

Τι επιστρέφεται#

Αληθές σε επιτυχία, ψευδές σε αποτυχία. Οι περιπτώσεις αποτυχίας είναι σπάνιες - η συνηθέστερη είναι το πέρασμα ενός hash που εξαρχής δεν ήταν tied σε αρχείο DBM, οπότε η dbmclose επιστρέφει ψευδές και θέτει το $!. Τα περισσότερα προγράμματα δεν ελέγχουν την τιμή επιστροφής· τα ενδιαφέροντα σφάλματα (γεμάτος δίσκος, υπέρβαση ορίου χώρου) εμφανίζονται στις εγγραφές που προηγήθηκαν του κλεισίματος, όχι στην ίδια την dbmclose. Ελέγξτε την όταν το αρχείο DBM βρίσκεται σε σύστημα αρχείων όπου η καθυστερημένη αποτυχία εγγραφής κατά το κλείσιμο είναι πιθανή:

dbmclose(%cache)
    or warn "dbmclose failed: $!";

Καθολική κατάσταση που επηρεάζει#

Η dbmclose διαβάζει και τροποποιεί την κατάσταση tie του HASH. Δεν αγγίζει καμία από τις συνήθεις ειδικές μεταβλητές που σχετίζονται με την I/O ($,, $\, $|, το επιλεγμένο filehandle)· η πρόσβαση 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;

Προστατευτείτε από το κλείσιμο ενός μη δεσμευμένου hash:

my %h;
dbmclose(%h)
    or warn "not tied to a DBM file: $!";   # warns

Συνδυάστε με ένα μπλοκ eval για να εντοπίσετε τοπικά τυχόν σφάλματα εκκαθάρισης χωρίς να ματαιωθεί ο περιβάλλων κώδικας:

eval {
    dbmclose(%cache) or die "dbmclose: $!";
    1;
} or warn $@;

Οριακές περιπτώσεις#

  • Hash όχι tied σε αρχείο DBM: επιστρέφει ψευδές, θέτει το $!. Δεν εγείρεται εξαίρεση. Το hash μένει αμετάβλητο.

  • Hash tied μέσω tie, όχι dbmopen: η dbmclose εξακολουθεί να λειτουργεί και είναι ισοδύναμη με την untie για αυτό το hash, επειδή η ίδια η dbmopen υλοποιείται ως tie εσωτερικά. Η ανάμειξη των δύο API είναι νόμιμη αλλά μπερδεύει - διαλέξτε ένα ανά hash και μείνετε σε αυτό.

  • Αναφορές εξακολουθούν να κρατούνται στο tied αντικείμενο: όπως η untie, η dbmclose διακόπτει τη δέσμευση μεταξύ του hash και του αρχείου DBM, αλλά αν άλλος κώδικας εξακολουθεί να κρατά αναφορά στο υποκείμενο tied αντικείμενο, η βιβλιοθήκη DBM ενδέχεται να μην απελευθερώσει στην πραγματικότητα τα handles της μέχρι να απορριφθεί αυτή η αναφορά. Το σύμπτωμα είναι ένα αρχείο DBM που μένει κλειδωμένο ή ανοιχτό πέρα από την κλήση dbmclose. Ένα πρόγραμμα με use warnings λαμβάνει σε αυτή την περίπτωση την προειδοποίηση untie attempted while N inner references still exist.

  • Κλήση της dbmclose δύο φορές στο ίδιο hash: η πρώτη κλήση πετυχαίνει, η δεύτερη επιστρέφει ψευδές. Κώδικας με στυλ idempotent θα πρέπει είτε να παρακολουθεί αν το hash είναι αυτή τη στιγμή tied είτε να αγνοεί την αποτυχία.

  • Το hash γίνεται local ή φεύγει από την εμβέλειά του χωρίς dbmclose: η δέσμευση διακόπτεται έμμεσα όταν το hash καταστρέφεται, και η βιβλιοθήκη DBM κλείνει το αρχείο ως μέρος αυτής της αποδόμησης. Το ρητό dbmclose είναι προτιμότερο, επειδή κάνει τις αποτυχίες εκκένωσης εγγραφής ορατές σε ένα γνωστό σημείο του προγράμματος.

Διαφορές από το upstream#

Πλήρως συμβατό με το upstream Perl 5.42.

Δείτε επίσης#

  • dbmopen - το μισό άνοιγμα του ζεύγους· κάθε dbmclose αντιστοιχεί σε ένα προηγούμενο dbmopen στο ίδιο hash

  • untie - η σύγχρονη, γενικού σκοπού αντικατάσταση· λειτουργεί για κάθε tied μεταβλητή, όχι μόνο για hashes δεσμευμένα σε DBM

  • tie - το σύγχρονο αντίστοιχο της dbmopen, που χρησιμοποιείται με τα AnyDBM_File, DB_File, GDBM_File, NDBM_File, ή SDBM_File για τη δέσμευση ενός hash σε αρχείο DBM

  • close - άσχετο, αλλά η ανάλογη λειτουργία για filehandles: χρειάζεται όταν σας ενδιαφέρει οι αποτυχίες εκκένωσης εγγραφής να εμφανίζονται σε ένα γνωστό σημείο