--- /dev/null
+<HTML>
+<HEAD>
+ <TITLE>IO::WrapTie 2.102</TITLE>
+</HEAD>
+<BODY
+ bgcolor="#FFFFFF" link="#CC3366" vlink="#993366" alink="#FF6666">
+<FONT FACE="sans-serif" SIZE=-1><A HREF="http://www.zeegee.com" TARGET="_top"><IMG SRC="icons/zeegee.gif" ALT="ZeeGee Software" ALIGN="RIGHT" BORDER="0"></A><A NAME="__TOP__"><H1>IO::WrapTie 2.102</H1>
+</A><UL>
+<LI> <A NAME="menu:NAME"><A HREF="#NAME">NAME</A></A>
+<LI> <A NAME="menu:SYNOPSIS"><A HREF="#SYNOPSIS">SYNOPSIS</A></A>
+<LI> <A NAME="menu:DESCRIPTION"><A HREF="#DESCRIPTION">DESCRIPTION</A></A>
+<LI> <A NAME="menu:HOW_IT_ALL_WORKS"><A HREF="#HOW_IT_ALL_WORKS">HOW IT ALL WORKS</A></A>
+<UL>
+<LI> <A NAME="menu:The_data_structures"><A HREF="#The_data_structures">The data structures</A></A>
+<LI> <A NAME="menu:How_wraptie_works"><A HREF="#How_wraptie_works">How wraptie() works</A></A>
+<LI> <A NAME="menu:How_I_O_operators_work_on_the_master"><A HREF="#How_I_O_operators_work_on_the_master">How I/O operators work (on the master)</A></A>
+<LI> <A NAME="menu:How_methods_work_on_the_master"><A HREF="#How_methods_work_on_the_master">How methods work (on the master)</A></A>
+</UL>
+<LI> <A NAME="menu:NOTES"><A HREF="#NOTES">NOTES</A></A>
+<LI> <A NAME="menu:WARNINGS"><A HREF="#WARNINGS">WARNINGS</A></A>
+<LI> <A NAME="menu:VERSION"><A HREF="#VERSION">VERSION</A></A>
+<LI> <A NAME="menu:AUTHOR"><A HREF="#AUTHOR">AUTHOR</A></A>
+</UL>
+
+
+<P><HR>
+<A NAME="NAME"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NAME</H2></A>
+
+
+<P>IO::WrapTie - wrap tieable objects in IO::Handle interface
+
+
+<P><I>This is currently Alpha code, released for comments.
+ Please give me your feedback!</I>
+
+
+
+<P><HR>
+<A NAME="SYNOPSIS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> SYNOPSIS</H2></A>
+
+
+<P>First of all, you'll need tie(), so:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ require 5.004;
+</PRE></FONT>
+
+<P><I>Function interface (experimental).</I>
+Use this with any existing class...
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ use IO::WrapTie;
+ use FooHandle; ### implements TIEHANDLE interface
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ ### Suppose we want a "FooHandle->new(&FOO_RDWR, 2)".
+ ### We can instead say...
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ $FH = wraptie('FooHandle', &FOO_RDWR, 2);
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ ### Now we can use...
+ print $FH "Hello, "; ### traditional operator syntax...
+ $FH->print("world!\n"); ### ...and OO syntax as well!
+</PRE></FONT>
+
+<P><I>OO interface (preferred).</I>
+You can inherit from the IO::WrapTie::Slave mixin to get a
+nifty <CODE>new_tie()</CODE> constructor...
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ #------------------------------
+ package FooHandle; ### a class which can TIEHANDLE
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ use IO::WrapTie;
+ @ISA = qw(IO::WrapTie::Slave); ### inherit new_tie()
+ ...
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ #------------------------------
+ package main;
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ $FH = FooHandle->new_tie(&FOO_RDWR, 2); ### $FH is an IO::WrapTie::Master
+ print $FH "Hello, "; ### traditional operator syntax
+ $FH->print("world!\n"); ### OO syntax
+</PRE></FONT>
+
+<P>See IO::Scalar as an example. It also shows you how to create classes
+which work both with and without 5.004.
+
+
+
+<P><HR>
+<A NAME="DESCRIPTION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> DESCRIPTION</H2></A>
+
+
+<P>Suppose you have a class <CODE>FooHandle</CODE>, where...
+
+
+
+<UL>
+<P><LI>
+<P><B>FooHandle does not inherit from IO::Handle;</B> that is, it performs
+filehandle-like I/O, but to something other than an underlying
+file descriptor. Good examples are IO::Scalar (for printing to a
+string) and IO::Lines (for printing to an array of lines).
+
+<P><LI>
+<P><B>FooHandle implements the TIEHANDLE interface</B> (see <A HREF="perltie.pm.html">perltie</A>);
+that is, it provides methods TIEHANDLE, GETC, PRINT, PRINTF,
+READ, and READLINE.
+
+<P><LI>
+<P><B>FooHandle implements the traditional OO interface</B> of
+FileHandle and IO::Handle; i.e., it contains methods like getline(),
+read(), print(), seek(), tell(), eof(), etc.
+
+</UL>
+
+
+<P>Normally, users of your class would have two options:
+
+
+
+<UL>
+<P><LI>
+<P><B>Use only OO syntax,</B> and forsake named I/O operators like 'print'.
+
+<P><LI>
+<P><B>Use with tie,</B> and forsake treating it as a first-class object
+(i.e., class-specific methods can only be invoked through the underlying
+object via tied()... giving the object a "split personality").
+
+</UL>
+
+
+<P>But now with IO::WrapTie, you can say:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $WT = wraptie('FooHandle', &FOO_RDWR, 2);
+ $WT->print("Hello, world\n"); ### OO syntax
+ print $WT "Yes!\n"; ### Named operator syntax too!
+ $WT->weird_stuff; ### Other methods!
+</PRE></FONT>
+
+<P>And if you're authoring a class like FooHandle, just have it inherit
+from <CODE>IO::WrapTie::Slave</CODE> and that first line becomes even prettier:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $WT = FooHandle->new_tie(&FOO_RDWR, 2);
+</PRE></FONT>
+
+<P><B>The bottom line:</B> now, almost any class can look and work exactly like
+an IO::Handle... and be used both with OO and non-OO filehandle syntax.
+
+
+
+<P><HR>
+<A NAME="HOW_IT_ALL_WORKS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> HOW IT ALL WORKS</H2></A>
+
+
+
+<P><HR>
+<A NAME="The_data_structures"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> The data structures</H3></A>
+
+
+<P>Consider this example code, using classes in this distribution:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ use IO::Scalar;
+ use IO::WrapTie;
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ $WT = wraptie('IO::Scalar',\$s);
+ print $WT "Hello, ";
+ $WT->print("world!\n");
+</PRE></FONT>
+
+<P>In it, the wraptie() function creates a data structure as follows:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ * $WT is a blessed reference to a tied filehandle
+ $WT glob; that glob is tied to the "Slave" object.
+ | * You would do all your i/o with $WT directly.
+ |
+ |
+ | ,---isa--> IO::WrapTie::Master >--isa--> IO::Handle
+ V /
+ .-------------.
+ | |
+ | | * Perl i/o operators work on the tied object,
+ | "Master" | invoking the TIEHANDLE methods.
+ | | * Method invocations are delegated to the tied
+ | | slave.
+ `-------------'
+ |
+ tied(*$WT) | .---isa--> IO::WrapTie::Slave
+ V /
+ .-------------.
+ | |
+ | "Slave" | * Instance of FileHandle-like class which doesn't
+ | | actually use file descriptors, like IO::Scalar.
+ | IO::Scalar | * The slave can be any kind of object.
+ | | * Must implement the TIEHANDLE interface.
+ `-------------'
+</PRE></FONT>
+
+<P><I>NOTE:</I> just as an IO::Handle is really just a blessed reference to a
+<I>traditional</I> filehandle glob... so also, an IO::WrapTie::Master
+is really just a blessed reference to a filehandle
+glob <I>which has been tied to some "slave" class.</I>
+
+
+
+<P><HR>
+<A NAME="How_wraptie_works"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> How wraptie() works</H3></A>
+
+
+
+<OL>
+<P><LI>
+<P>The call to function <CODE>wraptie(SLAVECLASS, TIEARGS...)</CODE> is
+passed onto <CODE>IO::WrapTie::Master::new()</CODE>.
+Note that class IO::WrapTie::Master is a subclass of IO::Handle.
+
+<P><LI>
+<P>The <CODE>IO::WrapTie::Master::new</CODE> method creates a new IO::Handle object,
+reblessed into class IO::WrapTie::Master. This object is the <I>master</I>,
+which will be returned from the constructor. At the same time...
+
+<P><LI>
+<P>The <CODE>new</CODE> method also creates the <I>slave</I>: this is an instance
+of SLAVECLASS which is created by tying the master's IO::Handle
+to SLAVECLASS via <CODE>tie(HANDLE, SLAVECLASS, TIEARGS...)</CODE>.
+This call to <CODE>tie()</CODE> creates the slave in the following manner:
+
+<P><LI>
+<P>Class SLAVECLASS is sent the message <CODE>TIEHANDLE(TIEARGS...)</CODE>; it
+will usually delegate this to <CODE>SLAVECLASS::new(TIEARGS...)</CODE>, resulting
+in a new instance of SLAVECLASS being created and returned.
+
+<P><LI>
+<P>Once both master and slave have been created, the master is returned
+to the caller.
+
+</OL>
+
+
+
+<P><HR>
+<A NAME="How_I_O_operators_work_on_the_master"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> How I/O operators work (on the master)</H3></A>
+
+
+<P>Consider using an i/o operator on the master:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ print $WT "Hello, world!\n";
+</PRE></FONT>
+
+<P>Since the master ($WT) is really a [blessed] reference to a glob,
+the normal Perl i/o operators like <CODE>print</CODE> may be used on it.
+They will just operate on the symbol part of the glob.
+
+
+<P>Since the glob is tied to the slave, the slave's PRINT method
+(part of the TIEHANDLE interface) will be automatically invoked.
+
+
+<P>If the slave is an IO::Scalar, that means IO::Scalar::PRINT will be
+invoked, and that method happens to delegate to the <CODE>print()</CODE> method
+of the same class. So the <I>real</I> work is ultimately done by
+IO::Scalar::print().
+
+
+
+<P><HR>
+<A NAME="How_methods_work_on_the_master"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> How methods work (on the master)</H3></A>
+
+
+<P>Consider using a method on the master:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $WT->print("Hello, world!\n");
+</PRE></FONT>
+
+<P>Since the master ($WT) is blessed into the class IO::WrapTie::Master,
+Perl first attempts to find a <CODE>print()</CODE> method there. Failing that,
+Perl next attempts to find a <CODE>print()</CODE> method in the superclass,
+IO::Handle. It just so happens that there <I>is</I> such a method;
+that method merely invokes the <CODE>print</CODE> i/o operator on the self object...
+and for that, see above!
+
+
+<P>But let's suppose we're dealing with a method which <I>isn't</I> part
+of IO::Handle... for example:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ my $sref = $WT->sref;
+</PRE></FONT>
+
+<P>In this case, the intuitive behavior is to have the master delegate the
+method invocation to the slave (now do you see where the designations
+come from?). This is indeed what happens: IO::WrapTie::Master contains
+an AUTOLOAD method which performs the delegation.
+
+
+<P>So: when <CODE>sref()</CODE> can't be found in IO::Handle, the AUTOLOAD method
+of IO::WrapTie::Master is invoked, and the standard behavior of
+delegating the method to the underlying slave (here, an IO::Scalar)
+is done.
+
+
+<P>Sometimes, to get this to work properly, you may need to create
+a subclass of IO::WrapTie::Master which is an effective master for
+<I>your</I> class, and do the delegation there.
+
+
+
+<P><HR>
+<A NAME="NOTES"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NOTES</H2></A>
+
+
+<P><B>Why not simply use the object's OO interface?</B>
+ Because that means forsaking the use of named operators
+like print(), and you may need to pass the object to a subroutine
+which will attempt to use those operators:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $O = FooHandle->new(&FOO_RDWR, 2);
+ $O->print("Hello, world\n"); ### OO syntax is okay, BUT....
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ sub nope { print $_[0] "Nope!\n" }
+ X nope($O); ### ERROR!!! (not a glob ref)
+</PRE></FONT>
+
+<P><B>Why not simply use tie()?</B>
+ Because (1) you have to use tied() to invoke methods in the
+object's public interface (yuck), and (2) you may need to pass
+the tied symbol to another subroutine which will attempt to treat
+it in an OO-way... and that will break it:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ tie *T, 'FooHandle', &FOO_RDWR, 2;
+ print T "Hello, world\n"; ### Operator is okay, BUT...
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ tied(*T)->other_stuff; ### yuck! AND...
+</PRE></FONT>
+<FONT SIZE=3 FACE="courier"><PRE>
+ sub nope { shift->print("Nope!\n") }
+ X nope(\*T); ### ERROR!!! (method "print" on unblessed ref)
+</PRE></FONT>
+
+<P><B>Why a master and slave?
+ Why not simply write FooHandle to inherit from IO::Handle?</B>
+ I tried this, with an implementation similar to that of IO::Socket.
+The problem is that <I>the whole point is to use this with objects
+that don't have an underlying file/socket descriptor.</I>.
+Subclassing IO::Handle will work fine for the OO stuff, and fine with
+named operators <I>if</I> you tie()... but if you just attempt to say:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $IO = FooHandle->new(&FOO_RDWR, 2);
+ print $IO "Hello!\n";
+</PRE></FONT>
+
+<P>you get a warning from Perl like:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ Filehandle GEN001 never opened
+</PRE></FONT>
+
+<P>because it's trying to do system-level i/o on an (unopened) file
+descriptor. To avoid this, you apparently have to tie() the handle...
+which brings us right back to where we started! At least the
+IO::WrapTie mixin lets us say:
+
+<FONT SIZE=3 FACE="courier"><PRE>
+ $IO = FooHandle->new_tie(&FOO_RDWR, 2);
+ print $IO "Hello!\n";
+</PRE></FONT>
+
+<P>and so is not <I>too</I> bad. <CODE>:-)</CODE>
+
+
+
+<P><HR>
+<A NAME="WARNINGS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> WARNINGS</H2></A>
+
+
+<P>Remember: this stuff is for doing FileHandle-like i/o on things
+<I>without underlying file descriptors</I>. If you have an underlying
+file descriptor, you're better off just inheriting from IO::Handle.
+
+
+<P><B>Be aware that new_tie() always returns an instance of a
+kind of IO::WrapTie::Master...</B> it does <B>not</B> return an instance
+of the i/o class you're tying to!
+
+
+<P>Invoking some methods on the master object causes AUTOLOAD to delegate
+them to the slave object... so it <I>looks</I> like you're manipulating a
+"FooHandle" object directly, but you're not.
+
+
+<P>I have not explored all the ramifications of this use of tie().
+<I>Here there be dragons</I>.
+
+
+
+<P><HR>
+<A NAME="VERSION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> VERSION</H2></A>
+
+
+<P>$Id: WrapTie.pm,v 2.102 2001/08/17 02:06:33 eryq Exp $
+
+
+
+<P><HR>
+<A NAME="AUTHOR"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> AUTHOR</H2></A>
+
+
+<P>Eryq (<I><FILE><A HREF="mailto:eryq@zeegee.com">eryq@zeegee.com</A></FILE></I>).
+President, ZeeGee Software Inc (<I><FILE><A HREF="http://www.zeegee.com">http://www.zeegee.com</A></FILE></I>).
+
+<P><HR>
+<ADDRESS><FONT SIZE=-1>
+Generated Sun Dec 21 13:54:38 2003 by cvu_pod2html
+</FONT></ADDRESS>
+</FONT></BODY>
+</HTML>