Classes and OO

tie#

Bind a variable to a class so that every access to the variable dispatches through that class’s methods.

tie enchants VARIABLE so that subsequent reads, writes, and other operations on it are forwarded to CLASSNAME’s tie-interface methods (FETCH, STORE, FIRSTKEY, PRINT, …). LIST is passed to the class’s constructor (TIESCALAR, TIEARRAY, TIEHASH, or TIEHANDLE, depending on the sigil of VARIABLE). The constructor returns the underlying tied object, and that object — not VARIABLE — is the return value of tie. Keep it if you want to call extra methods on the implementation directly.

The method contract each class must satisfy is documented at length in perltie; this page documents tie the built-in.

Synopsis#

tie my $scalar, 'ScalarClass', @args;
tie my @array,  'ArrayClass',  @args;
tie my %hash,   'HashClass',   @args;
tie *FH,        'HandleClass', @args;

my $obj = tie my %h, 'HashClass', @args;   # keep the tied object

What you get back#

The object returned by the class’s TIE* constructor — an ordinary blessed reference, same as any other object. Call methods on it directly when the class exposes operations that don’t map onto plain variable access:

my $db = tie my %cache, 'My::Cache', path => '/var/cache/app.db';
$db->flush;                 # method on the tied object
$cache{key} = 'value';      # goes through STORE

tie does not return the variable itself. Code that writes my $x = tie ... and then treats $x as the scalar is a common beginner mistake; the scalar is $x only if you also tied $x, and the assignment target is the tied object, not the variable.

To recover the tied object from a variable later, use tied. To dissolve the binding, use untie.

Which constructor is called#

The sigil of VARIABLE picks the constructor. LIST is forwarded verbatim:

VARIABLE form

Constructor called

Interface reference

$scalar

CLASSNAME->TIESCALAR(LIST)

Tie::Scalar

@array

CLASSNAME->TIEARRAY(LIST)

Tie::Array

%hash

CLASSNAME->TIEHASH(LIST)

Tie::Hash

*FH (glob)

CLASSNAME->TIEHANDLE(LIST)

Tie::Handle

The constructor’s arguments are conventionally those you’d pass to something like dbm_open(3) — a filename, a mode, a permission mask — but anything the class expects is fine.

Methods each class must provide#

tie itself only invokes TIE*. Every other operation on the variable dispatches to a method named after that operation. Not all methods are mandatory — missing methods make the corresponding operations fail with a runtime error. The full menus are:

Tied scalar (TIESCALAR):

TIESCALAR classname, LIST
FETCH     this
STORE     this, value
DESTROY   this
UNTIE     this

Tied array (TIEARRAY):

TIEARRAY  classname, LIST
FETCH     this, index
STORE     this, index, value
FETCHSIZE this
STORESIZE this, count
CLEAR     this
PUSH      this, LIST
POP       this
SHIFT     this
UNSHIFT   this, LIST
SPLICE    this, offset, length, LIST
EXTEND    this, count
DELETE    this, index
EXISTS    this, index
DESTROY   this
UNTIE     this

Tied hash (TIEHASH):

TIEHASH   classname, LIST
FETCH     this, key
STORE     this, key, value
DELETE    this, key
CLEAR     this
EXISTS    this, key
FIRSTKEY  this
NEXTKEY   this, lastkey
SCALAR    this
DESTROY   this
UNTIE     this

Tied filehandle (TIEHANDLE):

TIEHANDLE this, LIST
READ      this, scalar, length, offset
READLINE  this
GETC      this
WRITE     this, scalar, length, offset
PRINT     this, LIST
PRINTF    this, format, LIST
BINMODE   this
EOF       this
FILENO    this
SEEK      this, position, whence
TELL      this
OPEN      this, mode, LIST
CLOSE     this
DESTROY   this
UNTIE     this

See perltie for the full specification (method signatures, when each is called, defaults inherited from the Tie::* base classes).

Examples#

Bind a hash to an on-disk DBM file and iterate with each. keys and values would materialise the whole set at once — for large DBM files that’s expensive:

use NDBM_File;
tie(my %HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);
while (my ($key, $val) = each %HIST) {
    print $key, ' = ', unpack('L', $val), "\n";
}

Keep the constructor’s return value so you can talk to the tied object directly:

my $impl = tie my %cache, 'My::Cache', ttl => 60;
$cache{session} = $data;    # STORE
$impl->expire_now;           # direct method call

Tie a scalar to a read-only class that logs every access:

package Tie::Logged {
    sub TIESCALAR { my ($class, $v) = @_; bless \$v, $class }
    sub FETCH     { my $self = shift; warn "read\n";  $$self }
    sub STORE     { my ($s, $v) = @_;  warn "write\n"; $$s = $v }
}

tie my $x, 'Tie::Logged', 42;
print $x;           # warns "read",  prints 42
$x = 99;            # warns "write"

Tie a filehandle to a class that captures output into a string:

package Tie::StringHandle {
    sub TIEHANDLE { my $c = shift; bless { buf => '' }, $c }
    sub PRINT     { my $s = shift; $s->{buf} .= join '', @_; 1 }
    sub buf       { $_[0]->{buf} }
}

tie *OUT, 'Tie::StringHandle';
print OUT "hello\n";
print OUT "world\n";
my $obj = tied *OUT;
print $obj->buf;    # "hello\nworld\n"

Edge cases#

  • Return value is the object, not the variable. my $r = tie my %h, ... binds $r to the tied object. Assigning to $r assigns to a scalar; it does not write through to %h.

  • Module must be loaded first. Unlike dbmopen, tie does not use or require CLASSNAME for you. Load it explicitly:

    use My::TiedClass;
    tie my %h, 'My::TiedClass';
    

    Forgetting this is the typical cause of Can't locate object method "TIEHASH" via package ....

  • Missing methods are fatal at the point of use, not at tie time. A tied hash whose class defines FETCH but not STORE ties successfully, then raises Can't locate object method "STORE" ... on the first assignment.

  • Sigil mismatch is a tie-time error. tie picks the constructor from the variable’s sigil, so a class that only defines TIESCALAR cannot be tie-d to a hash — the lookup of TIEHASH fails at the tie call itself.

  • tieing a tied variable implicitly unties the previous binding first, triggering UNTIE and eventually DESTROY on the old object (once the last reference to it drops).

  • local on a tied variable saves and restores the binding, not just the value. At scope exit the variable is re-tied to its original object.

  • Holding an extra reference to the tied object keeps it alive past untie. Under use warnings this produces a untie attempted while N inner references still exist warning. Drop the reference (e.g. undef $obj) before calling untie if you want DESTROY to fire promptly.

  • tie does not stash the object inside the variable in any user-visible way — use tied to retrieve it; there’s no dereference syntax that exposes it.

  • Performance. Every operation on a tied variable dispatches through a method call. In tight loops this is visibly slower than a plain variable; for bulk work, read into a plain array or hash first, operate, then write back.

Differences from upstream#

Fully compatible with upstream Perl 5.42.

See also#

  • tied — recover the object a variable is currently tied to, or undef if it isn’t tied

  • untie — dissolve the binding and let the tied object be destroyed

  • bless — the low-level primitive TIE* constructors use to turn a reference into an object

  • dbmopen — older shortcut for the specific case of tying a hash to a DBM file; loads the DBM class for you, which tie does not

  • ref — inspect the class of the object returned by tie