--- name: dbmopen signature: 'dbmopen HASH, DBNAME, MASK' since: 5.0 status: documented categories: ["I/O", "Classes and OO"] --- ```{index} single: dbmopen; Perl built-in ``` *[I/O](../perlfunc-by-category) · [Classes and OO](../perlfunc-by-category)* # dbmopen Bind a DBM file on disk to a hash so hash reads and writes become lookups and stores in the database. `dbmopen` is the old-style way to tie a hash to a `dbm`, `ndbm`, `sdbm`, `gdbm`, or Berkeley DB file. It has been largely superseded by [`tie`](tie) with an explicit DBM backend module (`DB_File`, `GDBM_File`, `SDBM_File`, `NDBM_File`, `AnyDBM_File`), which gives you control over which implementation is used and over per-backend options. Reach for `dbmopen` when you are reading legacy code or when the one-liner brevity matters more than backend choice. Unlike [`open`](open), the first argument is **not** a filehandle — it is the hash that will be bound. `HASH` is written with the `%` sigil. ## Synopsis ```perl dbmopen %HASH, $DBNAME, $MASK dbmopen(%HASH, $DBNAME, 0) # open existing only; never create dbmclose %HASH # or: untie %HASH ``` ## What you get back A true value on success, a false value on failure. On failure [`$!`](../perlvar) is set to the system error that prevented the bind. The common failure cases are "database does not exist and `MASK` is `0`" and permission errors on the backing files. ```perl dbmopen(%cache, $path, 0) or die "cache $path missing or unreadable: $!"; ``` After a successful call, `%HASH` behaves like any other hash: `$HASH{key} = $value` writes to the database, `$HASH{key}` reads from it, [`delete`](delete) removes an entry, [`exists`](exists) tests membership, and [`each`](each) / [`keys`](keys) / [`values`](values) iterate. The data lives on disk; the hash is only a view. ## Arguments - **`HASH`** — the hash variable to bind. Must be written with `%`. Any existing contents are discarded. The hash stays bound until [`dbmclose`](dbmclose) or [`untie`](untie) is called on it, or until it goes out of scope. - **`DBNAME`** — the database pathname **without** the backend's file extension. Traditional `dbm` / `sdbm` stores use two files named `` `DBNAME.dir` `` and `` `DBNAME.pag` ``; `gdbm` and Berkeley DB use a single file. Passing `"/var/lib/app/cache"` opens `/var/lib/app/cache.dir` + `/var/lib/app/cache.pag` under `sdbm`, or `/var/lib/app/cache` under `gdbm`. - **`MASK`** — creation mode for any files that have to be created, in the same form as the third argument to [`chmod`](chmod) (typically an octal literal like `0666` or `0644`). The active [`umask`](umask) is applied to `MASK`, so real on-disk permissions are `MASK & ~umask`. **A `MASK` of `0` suppresses creation**: if the database does not already exist, `dbmopen` returns false and [`$!`](../perlvar) is set. ## Global state it touches - [`$!`](../perlvar) — set on failure (database missing, permission denied, backing store corrupt). - The active [`umask`](umask) — masks `MASK` when new backing files are created. ## Examples Open a history database, iterate with [`each`](each), then close: ```perl dbmopen(%HIST, '/usr/lib/news/history', 0666) or die "open history: $!"; while (my ($key, $val) = each %HIST) { print $key, ' = ', unpack('L', $val), "\n"; } dbmclose %HIST; ``` Open read-only, refusing to create the database: ```perl dbmopen(%cache, "$ENV{HOME}/.app/cache", 0) or die "no cache at $ENV{HOME}/.app/cache: $!"; my $hit = $cache{$key}; dbmclose %cache; ``` Pick a specific backend by loading its module before calling `dbmopen`. `AnyDBM_File` consults `@AnyDBM_File::ISA` to decide which implementation `dbmopen` uses: ```perl use DB_File; dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db", 0644) or die "open netscape history: $!"; ``` Write-protected database — assignment silently fails (or croaks depending on the backend); guard with [`eval`](eval) when you need to probe: ```perl dbmopen(%db, $path, 0) or die $!; my $writable = eval { $db{__probe__} = 1; delete $db{__probe__}; 1 }; warn "read-only\n" unless $writable; ``` Large database — avoid [`keys`](keys) / [`values`](values), which materialise the whole list in memory. Use [`each`](each) instead: ```perl dbmopen(%big, $path, 0) or die $!; while (my ($k, $v) = each %big) { process($k, $v); } dbmclose %big; ``` ## Edge cases - **Hash sigil is required.** `dbmopen %h, $name, 0666` — writing `$h` or `\%h` does not work. The first slot is the hash's name as a hash, not a reference. - **`MASK = 0` is the "open existing only" idiom.** A plausible-looking `0666` silently creates a fresh empty database if the file is missing, which is almost never what a reader wants on a cache lookup path. - **Extensions are managed by the backend.** Do not pass `"cache.dir"` or `"cache.pag"` — pass `"cache"`. `sdbm` appends `.dir` / `.pag`; `gdbm` writes to the bare name. - **One open per process for older DBM.** If the backend is the traditional `dbm(3)` library (rare today), a process may only have a single DBM open at a time. `sdbm` and `gdbm` do not have this limit. - **Value size limits.** `sdbm` caps keys + values at roughly 1008 bytes per record; oversize writes are truncated or rejected. `gdbm` and Berkeley DB have much higher limits. When in doubt, use `tie` with `DB_File` and check the backend's own limits. - **Numeric values are bytes on disk.** Storing `$h{k} = 42` writes the string `"42"`, not an integer. Pack explicitly with [`pack`](pack) / [`unpack`](unpack) when the field needs a fixed binary layout (as in the news-history example above). - **Closing is optional but recommended.** The bind is released when the hash goes out of scope, but explicit [`dbmclose`](dbmclose) or [`untie`](untie) flushes pending writes and surfaces close-time errors. - **Re-binding an already-bound hash.** Calling `dbmopen` on a hash that is already bound closes the previous binding first. ## Differences from upstream Fully compatible with upstream Perl 5.42. ## See also - [`dbmclose`](dbmclose) — release a `dbmopen` binding and flush pending writes - [`tie`](tie) — the modern replacement; pair with `DB_File`, `GDBM_File`, `SDBM_File`, or `AnyDBM_File` to pick a backend explicitly - [`untie`](untie) — release a binding made with either `dbmopen` or `tie` - [`each`](each) — stream entries without materialising the whole database in memory - [`umask`](umask) — masks the `MASK` argument when backing files are created - [`open`](open) — the ordinary file-open built-in, which takes a filehandle and not a hash