3 <TITLE>IO::WrapTie 2.102</TITLE>
6 bgcolor="#FFFFFF" link="#CC3366" vlink="#993366" alink="#FF6666">
7 <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>
9 <LI> <A NAME="menu:NAME"><A HREF="#NAME">NAME</A></A>
10 <LI> <A NAME="menu:SYNOPSIS"><A HREF="#SYNOPSIS">SYNOPSIS</A></A>
11 <LI> <A NAME="menu:DESCRIPTION"><A HREF="#DESCRIPTION">DESCRIPTION</A></A>
12 <LI> <A NAME="menu:HOW_IT_ALL_WORKS"><A HREF="#HOW_IT_ALL_WORKS">HOW IT ALL WORKS</A></A>
14 <LI> <A NAME="menu:The_data_structures"><A HREF="#The_data_structures">The data structures</A></A>
15 <LI> <A NAME="menu:How_wraptie_works"><A HREF="#How_wraptie_works">How wraptie() works</A></A>
16 <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>
17 <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>
19 <LI> <A NAME="menu:NOTES"><A HREF="#NOTES">NOTES</A></A>
20 <LI> <A NAME="menu:WARNINGS"><A HREF="#WARNINGS">WARNINGS</A></A>
21 <LI> <A NAME="menu:VERSION"><A HREF="#VERSION">VERSION</A></A>
22 <LI> <A NAME="menu:AUTHOR"><A HREF="#AUTHOR">AUTHOR</A></A>
27 <A NAME="NAME"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NAME</H2></A>
30 <P>IO::WrapTie - wrap tieable objects in IO::Handle interface
33 <P><I>This is currently Alpha code, released for comments.
34 Please give me your feedback!</I>
39 <A NAME="SYNOPSIS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> SYNOPSIS</H2></A>
42 <P>First of all, you'll need tie(), so:
44 <FONT SIZE=3 FACE="courier"><PRE>
48 <P><I>Function interface (experimental).</I>
49 Use this with any existing class...
51 <FONT SIZE=3 FACE="courier"><PRE>
53 use FooHandle; ### implements TIEHANDLE interface
55 <FONT SIZE=3 FACE="courier"><PRE>
56 ### Suppose we want a "FooHandle->new(&FOO_RDWR, 2)".
57 ### We can instead say...
59 <FONT SIZE=3 FACE="courier"><PRE>
60 $FH = wraptie('FooHandle', &FOO_RDWR, 2);
62 <FONT SIZE=3 FACE="courier"><PRE>
64 print $FH "Hello, "; ### traditional operator syntax...
65 $FH->print("world!\n"); ### ...and OO syntax as well!
68 <P><I>OO interface (preferred).</I>
69 You can inherit from the IO::WrapTie::Slave mixin to get a
70 nifty <CODE>new_tie()</CODE> constructor...
72 <FONT SIZE=3 FACE="courier"><PRE>
73 #------------------------------
74 package FooHandle; ### a class which can TIEHANDLE
76 <FONT SIZE=3 FACE="courier"><PRE>
78 @ISA = qw(IO::WrapTie::Slave); ### inherit new_tie()
81 <FONT SIZE=3 FACE="courier"><PRE>
82 #------------------------------
85 <FONT SIZE=3 FACE="courier"><PRE>
86 $FH = FooHandle->new_tie(&FOO_RDWR, 2); ### $FH is an IO::WrapTie::Master
87 print $FH "Hello, "; ### traditional operator syntax
88 $FH->print("world!\n"); ### OO syntax
91 <P>See IO::Scalar as an example. It also shows you how to create classes
92 which work both with and without 5.004.
97 <A NAME="DESCRIPTION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> DESCRIPTION</H2></A>
100 <P>Suppose you have a class <CODE>FooHandle</CODE>, where...
106 <P><B>FooHandle does not inherit from IO::Handle;</B> that is, it performs
107 filehandle-like I/O, but to something other than an underlying
108 file descriptor. Good examples are IO::Scalar (for printing to a
109 string) and IO::Lines (for printing to an array of lines).
112 <P><B>FooHandle implements the TIEHANDLE interface</B> (see <A HREF="perltie.pm.html">perltie</A>);
113 that is, it provides methods TIEHANDLE, GETC, PRINT, PRINTF,
117 <P><B>FooHandle implements the traditional OO interface</B> of
118 FileHandle and IO::Handle; i.e., it contains methods like getline(),
119 read(), print(), seek(), tell(), eof(), etc.
124 <P>Normally, users of your class would have two options:
130 <P><B>Use only OO syntax,</B> and forsake named I/O operators like 'print'.
133 <P><B>Use with tie,</B> and forsake treating it as a first-class object
134 (i.e., class-specific methods can only be invoked through the underlying
135 object via tied()... giving the object a "split personality").
140 <P>But now with IO::WrapTie, you can say:
142 <FONT SIZE=3 FACE="courier"><PRE>
143 $WT = wraptie('FooHandle', &FOO_RDWR, 2);
144 $WT->print("Hello, world\n"); ### OO syntax
145 print $WT "Yes!\n"; ### Named operator syntax too!
146 $WT->weird_stuff; ### Other methods!
149 <P>And if you're authoring a class like FooHandle, just have it inherit
150 from <CODE>IO::WrapTie::Slave</CODE> and that first line becomes even prettier:
152 <FONT SIZE=3 FACE="courier"><PRE>
153 $WT = FooHandle->new_tie(&FOO_RDWR, 2);
156 <P><B>The bottom line:</B> now, almost any class can look and work exactly like
157 an IO::Handle... and be used both with OO and non-OO filehandle syntax.
162 <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>
167 <A NAME="The_data_structures"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> The data structures</H3></A>
170 <P>Consider this example code, using classes in this distribution:
172 <FONT SIZE=3 FACE="courier"><PRE>
176 <FONT SIZE=3 FACE="courier"><PRE>
177 $WT = wraptie('IO::Scalar',\$s);
178 print $WT "Hello, ";
179 $WT->print("world!\n");
182 <P>In it, the wraptie() function creates a data structure as follows:
184 <FONT SIZE=3 FACE="courier"><PRE>
185 * $WT is a blessed reference to a tied filehandle
186 $WT glob; that glob is tied to the "Slave" object.
187 | * You would do all your i/o with $WT directly.
190 | ,---isa--> IO::WrapTie::Master >--isa--> IO::Handle
194 | | * Perl i/o operators work on the tied object,
195 | "Master" | invoking the TIEHANDLE methods.
196 | | * Method invocations are delegated to the tied
200 tied(*$WT) | .---isa--> IO::WrapTie::Slave
204 | "Slave" | * Instance of FileHandle-like class which doesn't
205 | | actually use file descriptors, like IO::Scalar.
206 | IO::Scalar | * The slave can be any kind of object.
207 | | * Must implement the TIEHANDLE interface.
211 <P><I>NOTE:</I> just as an IO::Handle is really just a blessed reference to a
212 <I>traditional</I> filehandle glob... so also, an IO::WrapTie::Master
213 is really just a blessed reference to a filehandle
214 glob <I>which has been tied to some "slave" class.</I>
219 <A NAME="How_wraptie_works"><H3><A HREF="#__TOP__"><IMG SRC="icons/h2bullet.gif" ALT="Top" BORDER="0"></A> How wraptie() works</H3></A>
225 <P>The call to function <CODE>wraptie(SLAVECLASS, TIEARGS...)</CODE> is
226 passed onto <CODE>IO::WrapTie::Master::new()</CODE>.
227 Note that class IO::WrapTie::Master is a subclass of IO::Handle.
230 <P>The <CODE>IO::WrapTie::Master::new</CODE> method creates a new IO::Handle object,
231 reblessed into class IO::WrapTie::Master. This object is the <I>master</I>,
232 which will be returned from the constructor. At the same time...
235 <P>The <CODE>new</CODE> method also creates the <I>slave</I>: this is an instance
236 of SLAVECLASS which is created by tying the master's IO::Handle
237 to SLAVECLASS via <CODE>tie(HANDLE, SLAVECLASS, TIEARGS...)</CODE>.
238 This call to <CODE>tie()</CODE> creates the slave in the following manner:
241 <P>Class SLAVECLASS is sent the message <CODE>TIEHANDLE(TIEARGS...)</CODE>; it
242 will usually delegate this to <CODE>SLAVECLASS::new(TIEARGS...)</CODE>, resulting
243 in a new instance of SLAVECLASS being created and returned.
246 <P>Once both master and slave have been created, the master is returned
254 <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>
257 <P>Consider using an i/o operator on the master:
259 <FONT SIZE=3 FACE="courier"><PRE>
260 print $WT "Hello, world!\n";
263 <P>Since the master ($WT) is really a [blessed] reference to a glob,
264 the normal Perl i/o operators like <CODE>print</CODE> may be used on it.
265 They will just operate on the symbol part of the glob.
268 <P>Since the glob is tied to the slave, the slave's PRINT method
269 (part of the TIEHANDLE interface) will be automatically invoked.
272 <P>If the slave is an IO::Scalar, that means IO::Scalar::PRINT will be
273 invoked, and that method happens to delegate to the <CODE>print()</CODE> method
274 of the same class. So the <I>real</I> work is ultimately done by
280 <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>
283 <P>Consider using a method on the master:
285 <FONT SIZE=3 FACE="courier"><PRE>
286 $WT->print("Hello, world!\n");
289 <P>Since the master ($WT) is blessed into the class IO::WrapTie::Master,
290 Perl first attempts to find a <CODE>print()</CODE> method there. Failing that,
291 Perl next attempts to find a <CODE>print()</CODE> method in the superclass,
292 IO::Handle. It just so happens that there <I>is</I> such a method;
293 that method merely invokes the <CODE>print</CODE> i/o operator on the self object...
294 and for that, see above!
297 <P>But let's suppose we're dealing with a method which <I>isn't</I> part
298 of IO::Handle... for example:
300 <FONT SIZE=3 FACE="courier"><PRE>
301 my $sref = $WT->sref;
304 <P>In this case, the intuitive behavior is to have the master delegate the
305 method invocation to the slave (now do you see where the designations
306 come from?). This is indeed what happens: IO::WrapTie::Master contains
307 an AUTOLOAD method which performs the delegation.
310 <P>So: when <CODE>sref()</CODE> can't be found in IO::Handle, the AUTOLOAD method
311 of IO::WrapTie::Master is invoked, and the standard behavior of
312 delegating the method to the underlying slave (here, an IO::Scalar)
316 <P>Sometimes, to get this to work properly, you may need to create
317 a subclass of IO::WrapTie::Master which is an effective master for
318 <I>your</I> class, and do the delegation there.
323 <A NAME="NOTES"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NOTES</H2></A>
326 <P><B>Why not simply use the object's OO interface?</B>
327 Because that means forsaking the use of named operators
328 like print(), and you may need to pass the object to a subroutine
329 which will attempt to use those operators:
331 <FONT SIZE=3 FACE="courier"><PRE>
332 $O = FooHandle->new(&FOO_RDWR, 2);
333 $O->print("Hello, world\n"); ### OO syntax is okay, BUT....
335 <FONT SIZE=3 FACE="courier"><PRE>
336 sub nope { print $_[0] "Nope!\n" }
337 X nope($O); ### ERROR!!! (not a glob ref)
340 <P><B>Why not simply use tie()?</B>
341 Because (1) you have to use tied() to invoke methods in the
342 object's public interface (yuck), and (2) you may need to pass
343 the tied symbol to another subroutine which will attempt to treat
344 it in an OO-way... and that will break it:
346 <FONT SIZE=3 FACE="courier"><PRE>
347 tie *T, 'FooHandle', &FOO_RDWR, 2;
348 print T "Hello, world\n"; ### Operator is okay, BUT...
350 <FONT SIZE=3 FACE="courier"><PRE>
351 tied(*T)->other_stuff; ### yuck! AND...
353 <FONT SIZE=3 FACE="courier"><PRE>
354 sub nope { shift->print("Nope!\n") }
355 X nope(\*T); ### ERROR!!! (method "print" on unblessed ref)
358 <P><B>Why a master and slave?
359 Why not simply write FooHandle to inherit from IO::Handle?</B>
360 I tried this, with an implementation similar to that of IO::Socket.
361 The problem is that <I>the whole point is to use this with objects
362 that don't have an underlying file/socket descriptor.</I>.
363 Subclassing IO::Handle will work fine for the OO stuff, and fine with
364 named operators <I>if</I> you tie()... but if you just attempt to say:
366 <FONT SIZE=3 FACE="courier"><PRE>
367 $IO = FooHandle->new(&FOO_RDWR, 2);
368 print $IO "Hello!\n";
371 <P>you get a warning from Perl like:
373 <FONT SIZE=3 FACE="courier"><PRE>
374 Filehandle GEN001 never opened
377 <P>because it's trying to do system-level i/o on an (unopened) file
378 descriptor. To avoid this, you apparently have to tie() the handle...
379 which brings us right back to where we started! At least the
380 IO::WrapTie mixin lets us say:
382 <FONT SIZE=3 FACE="courier"><PRE>
383 $IO = FooHandle->new_tie(&FOO_RDWR, 2);
384 print $IO "Hello!\n";
387 <P>and so is not <I>too</I> bad. <CODE>:-)</CODE>
392 <A NAME="WARNINGS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> WARNINGS</H2></A>
395 <P>Remember: this stuff is for doing FileHandle-like i/o on things
396 <I>without underlying file descriptors</I>. If you have an underlying
397 file descriptor, you're better off just inheriting from IO::Handle.
400 <P><B>Be aware that new_tie() always returns an instance of a
401 kind of IO::WrapTie::Master...</B> it does <B>not</B> return an instance
402 of the i/o class you're tying to!
405 <P>Invoking some methods on the master object causes AUTOLOAD to delegate
406 them to the slave object... so it <I>looks</I> like you're manipulating a
407 "FooHandle" object directly, but you're not.
410 <P>I have not explored all the ramifications of this use of tie().
411 <I>Here there be dragons</I>.
416 <A NAME="VERSION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> VERSION</H2></A>
419 <P>$Id: WrapTie.pm,v 2.102 2001/08/17 02:06:33 eryq Exp $
424 <A NAME="AUTHOR"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> AUTHOR</H2></A>
427 <P>Eryq (<I><FILE><A HREF="mailto:eryq@zeegee.com">eryq@zeegee.com</A></FILE></I>).
428 President, ZeeGee Software Inc (<I><FILE><A HREF="http://www.zeegee.com">http://www.zeegee.com</A></FILE></I>).
431 <ADDRESS><FONT SIZE=-1>
432 Generated Sun Dec 21 13:54:38 2003 by cvu_pod2html