Debian lenny version packages
[pkg-perl] / deb-src / libio-stringy-perl / io-stringy-2.110 / docs / IO / WrapTie.pm.html
1 <HTML>
2 <HEAD>
3   <TITLE>IO::WrapTie 2.102</TITLE>
4 </HEAD>
5 <BODY 
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>
8 </A><UL>
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>
13 <UL>
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>
18 </UL>
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>
23 </UL>
24
25
26 <P><HR>
27 <A NAME="NAME"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NAME</H2></A>
28
29
30 <P>IO::WrapTie - wrap tieable objects in IO::Handle interface
31
32
33 <P><I>This is currently Alpha code, released for comments.  
34   Please give me your feedback!</I>
35
36
37
38 <P><HR>
39 <A NAME="SYNOPSIS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> SYNOPSIS</H2></A>
40
41
42 <P>First of all, you'll need tie(), so:
43
44 <FONT SIZE=3 FACE="courier"><PRE>
45    require 5.004;
46 </PRE></FONT>
47
48 <P><I>Function interface (experimental).</I>
49 Use this with any existing class...
50
51 <FONT SIZE=3 FACE="courier"><PRE>
52    use IO::WrapTie;
53    use FooHandle;                  ### implements TIEHANDLE interface
54 </PRE></FONT>
55 <FONT SIZE=3 FACE="courier"><PRE>
56    ### Suppose we want a &quot;FooHandle-&gt;new(&amp;FOO_RDWR, 2)&quot;.
57    ### We can instead say...
58 </PRE></FONT>
59 <FONT SIZE=3 FACE="courier"><PRE>
60    $FH = wraptie('FooHandle', &amp;FOO_RDWR, 2); 
61 </PRE></FONT>
62 <FONT SIZE=3 FACE="courier"><PRE>
63    ### Now we can use...    
64    print $FH &quot;Hello, &quot;;            ### traditional operator syntax...
65    $FH-&gt;print(&quot;world!\n&quot;);         ### ...and OO syntax as well!
66 </PRE></FONT>
67
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...
71
72 <FONT SIZE=3 FACE="courier"><PRE>
73    #------------------------------    
74    package FooHandle;                        ### a class which can TIEHANDLE
75 </PRE></FONT>
76 <FONT SIZE=3 FACE="courier"><PRE>
77    use IO::WrapTie;  
78    @ISA = qw(IO::WrapTie::Slave);            ### inherit new_tie()
79    ...
80 </PRE></FONT>
81 <FONT SIZE=3 FACE="courier"><PRE>
82    #------------------------------    
83    package main; 
84 </PRE></FONT>
85 <FONT SIZE=3 FACE="courier"><PRE>
86    $FH = FooHandle-&gt;new_tie(&amp;FOO_RDWR, 2);   ### $FH is an IO::WrapTie::Master
87    print $FH &quot;Hello, &quot;;                      ### traditional operator syntax
88    $FH-&gt;print(&quot;world!\n&quot;);                   ### OO syntax
89 </PRE></FONT>
90
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.
93
94
95
96 <P><HR>
97 <A NAME="DESCRIPTION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> DESCRIPTION</H2></A>
98
99
100 <P>Suppose you have a class <CODE>FooHandle</CODE>, where...
101
102
103
104 <UL>
105 <P><LI>
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).
110
111 <P><LI>
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,
114 READ, and READLINE.
115
116 <P><LI>
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.
120
121 </UL>
122
123
124 <P>Normally, users of your class would have two options:
125
126
127
128 <UL>
129 <P><LI>
130 <P><B>Use only OO syntax,</B> and forsake named I/O operators like 'print'.
131
132 <P><LI>
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 &quot;split personality&quot;).
136
137 </UL>
138
139
140 <P>But now with IO::WrapTie, you can say:
141
142 <FONT SIZE=3 FACE="courier"><PRE>
143     $WT = wraptie('FooHandle', &amp;FOO_RDWR, 2);
144     $WT-&gt;print(&quot;Hello, world\n&quot;);   ### OO syntax
145     print $WT &quot;Yes!\n&quot;;             ### Named operator syntax too!
146     $WT-&gt;weird_stuff;               ### Other methods!
147 </PRE></FONT>
148
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:
151
152 <FONT SIZE=3 FACE="courier"><PRE>
153     $WT = FooHandle-&gt;new_tie(&amp;FOO_RDWR, 2);
154 </PRE></FONT>
155
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.
158
159
160
161 <P><HR>
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>
163
164
165
166 <P><HR>
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>
168
169
170 <P>Consider this example code, using classes in this distribution:
171
172 <FONT SIZE=3 FACE="courier"><PRE>
173     use IO::Scalar;
174     use IO::WrapTie;
175 </PRE></FONT>
176 <FONT SIZE=3 FACE="courier"><PRE>
177     $WT = wraptie('IO::Scalar',\$s);
178     print $WT &quot;Hello, &quot;;
179     $WT-&gt;print(&quot;world!\n&quot;);
180 </PRE></FONT>
181
182 <P>In it, the wraptie() function creates a data structure as follows:
183
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 &quot;Slave&quot; object.
187                |          * You would do all your i/o with $WT directly.
188                |       
189                |
190                |     ,---isa--&gt; IO::WrapTie::Master &gt;--isa--&gt; IO::Handle
191                V    /
192         .-------------. 
193         |             | 
194         |             |   * Perl i/o operators work on the tied object,  
195         |  &quot;Master&quot;   |     invoking the TIEHANDLE methods.
196         |             |   * Method invocations are delegated to the tied 
197         |             |     slave.
198         `-------------' 
199                |    
200     tied(*$WT) |     .---isa--&gt; IO::WrapTie::Slave
201                V    /   
202         .-------------.
203         |             |
204         |   &quot;Slave&quot;   |   * 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.
208         `-------------'
209 </PRE></FONT>
210
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 &quot;slave&quot; class.</I>
215
216
217
218 <P><HR>
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>
220
221
222
223 <OL>
224 <P><LI>
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.
228
229 <P><LI>
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...
233
234 <P><LI>
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:
239
240 <P><LI>
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.
244
245 <P><LI>
246 <P>Once both master and slave have been created, the master is returned
247 to the caller.  
248
249 </OL>
250
251
252
253 <P><HR>
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>
255
256
257 <P>Consider using an i/o operator on the master:
258
259 <FONT SIZE=3 FACE="courier"><PRE>
260     print $WT &quot;Hello, world!\n&quot;;   
261 </PRE></FONT>
262
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.
266
267
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.  
270
271
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 
275 IO::Scalar::print().
276
277
278
279 <P><HR>
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>
281
282
283 <P>Consider using a method on the master:
284
285 <FONT SIZE=3 FACE="courier"><PRE>
286     $WT-&gt;print(&quot;Hello, world!\n&quot;);
287 </PRE></FONT>
288
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!
295
296
297 <P>But let's suppose we're dealing with a method which <I>isn't</I> part
298 of IO::Handle... for example:
299
300 <FONT SIZE=3 FACE="courier"><PRE>
301     my $sref = $WT-&gt;sref;
302 </PRE></FONT>
303
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.  
308
309
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)
313 is done.
314
315
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.
319
320
321
322 <P><HR>
323 <A NAME="NOTES"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> NOTES</H2></A>
324
325
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:
330
331 <FONT SIZE=3 FACE="courier"><PRE>
332     $O = FooHandle-&gt;new(&amp;FOO_RDWR, 2);
333     $O-&gt;print(&quot;Hello, world\n&quot;);  ### OO syntax is okay, BUT....
334 </PRE></FONT>
335 <FONT SIZE=3 FACE="courier"><PRE>
336     sub nope { print $_[0] &quot;Nope!\n&quot; }
337  X  nope($O);                     ### ERROR!!! (not a glob ref)
338 </PRE></FONT>
339
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:
345
346 <FONT SIZE=3 FACE="courier"><PRE>
347     tie *T, 'FooHandle', &amp;FOO_RDWR, 2; 
348     print T &quot;Hello, world\n&quot;;   ### Operator is okay, BUT... 
349 </PRE></FONT>
350 <FONT SIZE=3 FACE="courier"><PRE>
351     tied(*T)-&gt;other_stuff;      ### yuck! AND...
352 </PRE></FONT>
353 <FONT SIZE=3 FACE="courier"><PRE>
354     sub nope { shift-&gt;print(&quot;Nope!\n&quot;) }
355  X  nope(\*T);                  ### ERROR!!! (method &quot;print&quot; on unblessed ref)
356 </PRE></FONT>
357
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:
365
366 <FONT SIZE=3 FACE="courier"><PRE>
367     $IO = FooHandle-&gt;new(&amp;FOO_RDWR, 2);
368     print $IO &quot;Hello!\n&quot;;
369 </PRE></FONT>
370
371 <P>you get a warning from Perl like:
372
373 <FONT SIZE=3 FACE="courier"><PRE>
374     Filehandle GEN001 never opened
375 </PRE></FONT>
376
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:
381
382 <FONT SIZE=3 FACE="courier"><PRE>
383     $IO = FooHandle-&gt;new_tie(&amp;FOO_RDWR, 2);
384     print $IO &quot;Hello!\n&quot;;
385 </PRE></FONT>
386
387 <P>and so is not <I>too</I> bad.  <CODE>:-)</CODE>
388
389
390
391 <P><HR>
392 <A NAME="WARNINGS"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> WARNINGS</H2></A>
393
394
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.
398
399
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!  
403
404
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 &quot;FooHandle&quot; object directly, but you're not.
408
409
410 <P>I have not explored all the ramifications of this use of tie().
411 <I>Here there be dragons</I>.
412
413
414
415 <P><HR>
416 <A NAME="VERSION"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> VERSION</H2></A>
417
418
419 <P>$Id: WrapTie.pm,v 2.102 2001/08/17 02:06:33 eryq Exp $
420
421
422
423 <P><HR>
424 <A NAME="AUTHOR"><H2><A HREF="#__TOP__"><IMG SRC="icons/h1bullet.gif" ALT="Top" BORDER="0"></A> AUTHOR</H2></A>
425
426
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>).
429
430 <P><HR>
431 <ADDRESS><FONT SIZE=-1>
432 Generated Sun Dec 21 13:54:38 2003 by cvu_pod2html
433 </FONT></ADDRESS>
434 </FONT></BODY>
435 </HTML>