package Tie::Handle; use 5.005_64; our $VERSION = '1.0'; =head1 NAME Tie::Handle, Tie::StdHandle - base class definitions for tied handles =head1 SYNOPSIS package NewHandle; require Tie::Handle; @ISA = (Tie::Handle); sub READ { ... } # Provide a needed method sub TIEHANDLE { ... } # Overrides inherited method package main; tie *FH, 'NewHandle'; =head1 DESCRIPTION This module provides some skeletal methods for handle-tying classes. See L for a list of the functions required in tying a handle to a package. The basic B package provides a C method, as well as methods C, C, C and C. For developers wishing to write their own tied-handle classes, the methods are summarized below. The L section not only documents these, but has sample code as well: =over =item TIEHANDLE classname, LIST The method invoked by the command C. Associates a new glob instance with the specified class. C would represent additional arguments (along the lines of L and compatriots) needed to complete the association. =item WRITE this, scalar, length, offset Write I bytes of data from I starting at I. =item PRINT this, LIST Print the values in I =item PRINTF this, format, LIST Print the values in I using I =item READ this, scalar, length, offset Read I bytes of data into I starting at I. =item READLINE this Read a single line =item GETC this Get a single character =item CLOSE this Close the handle =item OPEN this, filename (Re-)open the handle =item BINMODE this Specify content is binary =item EOF this Test for end of file. =item TELL this Return position in the file. =item SEEK this, offset, whence Position the file. Test for end of file. =item DESTROY this Free the storage associated with the tied handle referenced by I. This is rarely needed, as Perl manages its memory quite well. But the option exists, should a class wish to perform specific actions upon the destruction of an instance. =back =head1 MORE INFORMATION The L section contains an example of tying handles. =cut use Carp; sub new { my $pkg = shift; $pkg->TIEHANDLE(@_); } # "Grandfather" the new, a la Tie::Hash sub TIEHANDLE { my $pkg = shift; if (defined &{"{$pkg}::new"}) { carp "WARNING: calling ${pkg}->new since ${pkg}->TIEHANDLE is missing" if $^W; $pkg->new(@_); } else { croak "$pkg doesn't define a TIEHANDLE method"; } } sub PRINT { my $self = shift; if($self->can('WRITE') != \&WRITE) { my $buf = join(defined $, ? $, : "",@_); $buf .= $\ if defined $\; $self->WRITE($buf,length($buf),0); } else { croak ref($self)," doesn't define a PRINT method"; } } sub PRINTF { my $self = shift; if($self->can('WRITE') != \&WRITE) { my $buf = sprintf(shift,@_); $self->WRITE($buf,length($buf),0); } else { croak ref($self)," doesn't define a PRINTF method"; } } sub READLINE { my $pkg = ref $_[0]; croak "$pkg doesn't define a READLINE method"; } sub GETC { my $self = shift; if($self->can('READ') != \&READ) { my $buf; $self->READ($buf,1); return $buf; } else { croak ref($self)," doesn't define a GETC method"; } } sub READ { my $pkg = ref $_[0]; croak "$pkg doesn't define a READ method"; } sub WRITE { my $pkg = ref $_[0]; croak "$pkg doesn't define a WRITE method"; } sub CLOSE { my $pkg = ref $_[0]; croak "$pkg doesn't define a CLOSE method"; } package Tie::StdHandle; our @ISA = 'Tie::Handle'; use Carp; sub TIEHANDLE { my $class = shift; my $fh = do { \local *HANDLE}; bless $fh,$class; $fh->OPEN(@_) if (@_); return $fh; } sub EOF { eof($_[0]) } sub TELL { tell($_[0]) } sub FILENO { fileno($_[0]) } sub SEEK { seek($_[0],$_[1],$_[2]) } sub CLOSE { close($_[0]) } sub BINMODE { binmode($_[0]) } sub OPEN { $_[0]->CLOSE if defined($_[0]->FILENO); open($_[0],$_[1]); } sub READ { read($_[0],$_[1],$_[2]) } sub READLINE { my $fh = $_[0]; <$fh> } sub GETC { getc($_[0]) } sub WRITE { my $fh = $_[0]; print $fh substr($_[1],0,$_[2]) } 1;