# Tied filehandles A tied filehandle reroutes I/O the way a tied scalar reroutes reads and writes. Print to it and your `PRINT` runs; read a line and your `READLINE` runs. The classic uses are redirecting output somewhere unusual (into a string, across a network, through a filter) and embedding Perl in a host program that needs `STDOUT` and `STDERR` handled specially. The interface is larger than the others but mostly optional: you implement only the operations the handle will actually receive. The full menu is on the [`tie`](../../p5/core/perlfunc/tie) reference page; this chapter builds a class and explains the hooks and their timing. ## A complete class A write-only handle that collects everything printed to it into a string: ```perl use v5.36; package Collector { sub TIEHANDLE { my $class = shift; my $buf = ''; return bless \$buf, $class } sub PRINT { my $self = shift; $$self .= join($, // '', @_); return 1 } sub PRINTF { my $self = shift; my $fmt = shift; $$self .= sprintf($fmt, @_); return 1 } sub buffer { my $self = shift; return $$self } } tie *OUT, 'Collector'; print OUT "hello "; print OUT "world\n"; printf OUT "%d items\n", 3; my $obj = tied *OUT; print $obj->buffer; # hello world # 3 items ``` The object is a blessed scalar ref holding the accumulated text. The extra `buffer` method is reached through [`tied`](../../p5/core/perlfunc/tied), not through any I/O operation - that is the standard way a tie class exposes operations with no filehandle syntax. ## Tying the glob, not the scalar The first argument to [`tie`](../../p5/core/perlfunc/tie) for a handle must be a glob - it begins with an asterisk: - To tie a named handle: `tie *OUT, 'Collector'`. - To tie a handle held in a scalar `$fh`: `tie *$fh, 'Collector'`. Writing `tie $fh, ...` ties the *scalar* `$fh`, not the handle inside it - a common and confusing mistake. ## The method contract `TIEHANDLE classname, LIST` : The constructor; returns a blessed reference of any kind. It can hold whatever internal state the handle needs. `PRINT this, LIST` : Backs [`print`](../../p5/core/perlfunc/print) and [`say`](../../p5/core/perlfunc/say). It receives the printed list. Honour `$,` (the output field separator) between items and `$\` (the output record terminator) at the end if you want full fidelity - `print` does not insert them for you. `PRINTF this, format, LIST` : Backs [`printf`](../../p5/core/perlfunc/printf). It receives the format string and arguments; run them through [`sprintf`](../../p5/core/perlfunc/sprintf) yourself. `WRITE this, scalar, length, offset` : Backs [`syswrite`](../../p5/core/perlfunc/syswrite) - the raw, buffer-oriented write, distinct from `PRINT`. `READLINE this` : Backs `<$fh>` and [`readline`](../../p5/core/perlfunc/readline). In scalar context return the next line or `undef` at end of input; in list context return all remaining lines or an empty list. The returned strings should include the input record separator `$/`, matching what a real handle gives you. `READ this, scalar, length, offset` / `GETC this` : Back [`read`](../../p5/core/perlfunc/read) / [`sysread`](../../p5/core/perlfunc/sysread) and [`getc`](../../p5/core/perlfunc/getc) respectively. `OPEN`, `CLOSE`, `EOF`, `BINMODE`, `FILENO`, `SEEK`, `TELL` : Back the corresponding built-ins when used on the handle. Implement the ones that make sense for your backing store and leave the rest out. `DESTROY this` / `UNTIE this` : Optional cleanup, identical in role to the other tie types. A handle class often closes its backing resource here. ## Call timing - `print FH @list` and `say FH @list` → `PRINT`. `say` additionally localises `$\` to `"\n"` around the call, so a `PRINT` that honours `$\` handles `say` with no special case. - `printf FH $fmt, @args` → `PRINTF`. - `syswrite FH, $buf, $len, $off` → `WRITE`. - `` / `readline FH` → `READLINE`, in the surrounding context. - `read`/`sysread` → `READ`; `getc FH` → `GETC`. - `close FH`, `eof FH`, `binmode FH`, `seek`, `tell`, `fileno`, `open FH, ...` → the matching uppercase hook when defined. A note on `STDERR`: when `STDERR` is tied, its `PRINT` is what issues warnings and error messages. The runtime disables the tie for the duration of that call, so you can `warn` from inside `PRINT` without triggering infinite recursion. ## Minimum viable class There is no single mandatory method beyond `TIEHANDLE` - you implement whichever operations the handle will receive. An output-only handle needs `TIEHANDLE` plus `PRINT` (and usually `PRINTF`). An input-only handle needs `TIEHANDLE` plus `READLINE` (and perhaps `GETC` / `READ`). Operations whose hook is missing die at the point of use, so define exactly the set your callers exercise. ## The easy way: inherit from `Tie::StdHandle` `Tie::StdHandle` (shipped inside `Tie::Handle`) ties a handle onto a real underlying one: its `OPEN` opens an actual file and the I/O hooks forward to it. Inherit from it and override only the operations you want to intercept: ```perl package Doubler { use Tie::StdHandle; our @ISA = ('Tie::StdHandle'); sub READLINE { my $self = shift; my $line = $self->SUPER::READLINE; return defined $line ? $line . $line : undef; # echo each line twice } } my $data = "a\nb\n"; tie *DUP, 'Doubler'; tied(*DUP)->OPEN('<', \$data); print while defined($_ = ); # a # a # b # b ``` `READLINE` calls up to the base class for the real next line, then doubles it; every other operation flows through `Tie::StdHandle` unchanged. `Tie::Handle` (the parent) is the abstract base that documents the interface and supplies a default `PRINT`/`PRINTF` in terms of `WRITE`; `Tie::StdHandle` is the concrete, ready-to-use one. ## See also - [`tie`](../../p5/core/perlfunc/tie) - the built-in and the full handle method menu - [`tied`](../../p5/core/perlfunc/tied) - the only way to reach a handle class's non-I/O methods, like `buffer` above - [`print`](../../p5/core/perlfunc/print) and [`printf`](../../p5/core/perlfunc/printf) - the built-ins behind `PRINT` and `PRINTF` - [`readline`](../../p5/core/perlfunc/readline) - its page documents the scalar/list return contract `READLINE` must honour - [Tied scalars](scalars) - the simplest tie type, a good warm-up for the handle interface - `Tie::Handle` - the base-class module; `Tie::StdHandle` is the concrete version