1IO::WrapTie(3)        User Contributed Perl Documentation       IO::WrapTie(3)
2
3
4

NAME

6       IO::WrapTie - wrap tieable objects in IO::Handle interface
7
8       This is currently Alpha code, released for comments.
9         Please give me your feedback!
10

SYNOPSIS

12       First of all, you'll need tie(), so:
13
14          require 5.004;
15
16       Function interface (experimental).  Use this with any existing class...
17
18          use IO::WrapTie;
19          use FooHandle;                  ### implements TIEHANDLE interface
20
21          ### Suppose we want a "FooHandle->new(&FOO_RDWR, 2)".
22          ### We can instead say...
23
24          $FH = wraptie('FooHandle', &FOO_RDWR, 2);
25
26          ### Now we can use...
27          print $FH "Hello, ";            ### traditional operator syntax...
28          $FH->print("world!\n");         ### ...and OO syntax as well!
29
30       OO interface (preferred).  You can inherit from the "Slave" in
31       IO::WrapTie mixin to get a nifty new_tie() constructor...
32
33          #------------------------------
34          package FooHandle;                        ### a class which can TIEHANDLE
35
36          use IO::WrapTie;
37          @ISA = qw(IO::WrapTie::Slave);            ### inherit new_tie()
38          ...
39
40
41          #------------------------------
42          package main;
43
44          $FH = FooHandle->new_tie(&FOO_RDWR, 2);   ### $FH is an IO::WrapTie::Master
45          print $FH "Hello, ";                      ### traditional operator syntax
46          $FH->print("world!\n");                   ### OO syntax
47
48       See IO::Scalar as an example.  It also shows you how to create classes
49       which work both with and without 5.004.
50

DESCRIPTION

52       Suppose you have a class "FooHandle", where...
53
54       •   "FooHandle" does not inherit from IO::Handle. That is, it performs
55           file handle-like I/O, but to something other than an underlying
56           file descriptor. Good examples are IO::Scalar (for printing to a
57           string) and IO::Lines (for printing to an array of lines).
58
59       •   "FooHandle" implements the "TIEHANDLE" interface (see perltie).
60           That is, it provides methods "TIEHANDLE", "GETC", "PRINT",
61           "PRINTF", "READ", and "READLINE".
62
63       •   "FooHandle" implements the traditional OO interface of FileHandle
64           and IO::Handle. i.e., it contains methods like "getline", "read",
65           "print", "seek", "tell", "eof", etc.
66
67       Normally, users of your class would have two options:
68
69Use only OO syntax, and forsake named I/O operators like "print".
70
71Use with tie, and forsake treating it as a first-class object
72           (i.e., class-specific methods can only be invoked through the
73           underlying object via "tied"... giving the object a "split
74           personality").
75
76       But now with IO::WrapTie, you can say:
77
78           $WT = wraptie('FooHandle', &FOO_RDWR, 2);
79           $WT->print("Hello, world\n");   ### OO syntax
80           print $WT "Yes!\n";             ### Named operator syntax too!
81           $WT->weird_stuff;               ### Other methods!
82
83       And if you're authoring a class like "FooHandle", just have it inherit
84       from "IO::WrapTie::Slave" and that first line becomes even prettier:
85
86           $WT = FooHandle->new_tie(&FOO_RDWR, 2);
87
88       The bottom line: now, almost any class can look and work exactly like
89       an IO::Handle and be used both with OO and non-OO file handle syntax.
90

HOW IT ALL WORKS

92   The data structures
93       Consider this example code, using classes in this distribution:
94
95           use IO::Scalar;
96           use IO::WrapTie;
97
98           $WT = wraptie('IO::Scalar',\$s);
99           print $WT "Hello, ";
100           $WT->print("world!\n");
101
102       In it, the "wraptie" function creates a data structure as follows:
103
104                                 * $WT is a blessed reference to a tied filehandle
105                     $WT           glob; that glob is tied to the "Slave" object.
106                      |          * You would do all your i/o with $WT directly.
107                      |
108                      |
109                      |     ,---isa--> IO::WrapTie::Master >--isa--> IO::Handle
110                      V    /
111               .-------------.
112               |             |
113               |             |   * Perl i/o operators work on the tied object,
114               |  "Master"   |     invoking the C<TIEHANDLE> methods.
115               |             |   * Method invocations are delegated to the tied
116               |             |     slave.
117               `-------------'
118                      |
119           tied(*$WT) |     .---isa--> IO::WrapTie::Slave
120                      V    /
121               .-------------.
122               |             |
123               |   "Slave"   |   * Instance of FileHandle-like class which doesn't
124               |             |     actually use file descriptors, like IO::Scalar.
125               |  IO::Scalar |   * The slave can be any kind of object.
126               |             |   * Must implement the C<TIEHANDLE> interface.
127               `-------------'
128
129       NOTE: just as an IO::Handle is really just a blessed reference to a
130       traditional file handle glob. So also, an "IO::WrapTie::Master" is
131       really just a blessed reference to a file handle glob which has been
132       tied to some "slave" class.
133
134   How "wraptie" works
135       1.  The call to function "wraptie(SLAVECLASS, TIEARGS...)" is passed
136           onto IO::WrapTie::Master::new().  Note that class
137           "IO::WrapTie::Master" is a subclass of IO::Handle.
138
139       2.  The "IO::WrapTie::Master->new" method creates a new IO::Handle
140           object, re-blessed into class "IO::WrapTie::Master". This object is
141           the master, which will be returned from the constructor. At the
142           same time...
143
144       3.  The "new" method also creates the slave: this is an instance of
145           "SLAVECLASS" which is created by tying the master's IO::Handle to
146           "SLAVECLASS" via "tie".  This call to "tie" creates the slave in
147           the following manner:
148
149       4.  Class "SLAVECLASS" is sent the message "TIEHANDLE"; it will usually
150           delegate this to "SLAVECLASS->new(TIEARGS)", resulting in a new
151           instance of "SLAVECLASS" being created and returned.
152
153       5.  Once both master and slave have been created, the master is
154           returned to the caller.
155
156   How I/O operators work (on the master)
157       Consider using an i/o operator on the master:
158
159           print $WT "Hello, world!\n";
160
161       Since the master $WT is really a "blessed" reference to a glob, the
162       normal Perl I/O operators like "print" may be used on it.  They will
163       just operate on the symbol part of the glob.
164
165       Since the glob is tied to the slave, the slave's "PRINT" method (part
166       of the "TIEHANDLE" interface) will be automatically invoked.
167
168       If the slave is an IO::Scalar, that means "PRINT" in IO::Scalar will be
169       invoked, and that method happens to delegate to the "print" method of
170       the same class.  So the real work is ultimately done by "print" in
171       IO::Scalar.
172
173   How methods work (on the master)
174       Consider using a method on the master:
175
176           $WT->print("Hello, world!\n");
177
178       Since the master $WT is blessed into the class "IO::WrapTie::Master",
179       Perl first attempts to find a "print" method there.  Failing that, Perl
180       next attempts to find a "print" method in the super class, IO::Handle.
181       It just so happens that there is such a method; that method merely
182       invokes the "print" I/O operator on the self object...  and for that,
183       see above!
184
185       But let's suppose we're dealing with a method which isn't part of
186       IO::Handle... for example:
187
188           my $sref = $WT->sref;
189
190       In this case, the intuitive behavior is to have the master delegate the
191       method invocation to the slave (now do you see where the designations
192       come from?).  This is indeed what happens: "IO::WrapTie::Master"
193       contains an "AUTOLOAD" method which performs the delegation.
194
195       So: when "sref" can't be found in IO::Handle, the "AUTOLOAD" method of
196       "IO::WrapTie::Master" is invoked, and the standard behavior of
197       delegating the method to the underlying slave (here, an IO::Scalar) is
198       done.
199
200       Sometimes, to get this to work properly, you may need to create a
201       subclass of "IO::WrapTie::Master" which is an effective master for your
202       class, and do the delegation there.
203

NOTES

205       Why not simply use the object's OO interface?
206
207       Because that means forsaking the use of named operators like "print",
208       and you may need to pass the object to a subroutine which will attempt
209       to use those operators:
210
211           $O = FooHandle->new(&FOO_RDWR, 2);
212           $O->print("Hello, world\n");  ### OO syntax is okay, BUT....
213
214           sub nope { print $_[0] "Nope!\n" }
215        X  nope($O);                     ### ERROR!!! (not a glob ref)
216
217       Why not simply use tie()?
218           Because (1) you have to use "tied" to invoke methods in the
219       object's public interface (yuck), and (2) you may need to pass the tied
220       symbol to another subroutine which will attempt to treat it in an OO-
221       way... and that will break it:
222
223           tie *T, 'FooHandle', &FOO_RDWR, 2;
224           print T "Hello, world\n";   ### Operator is okay, BUT...
225
226           tied(*T)->other_stuff;      ### yuck! AND...
227
228           sub nope { shift->print("Nope!\n") }
229        X  nope(\*T);                  ### ERROR!!! (method "print" on unblessed ref)
230
231       Why a master and slave?
232
233           Why not simply write C<FooHandle> to inherit from L<IO::Handle?>
234       I tried this, with an implementation similar to that of L<IO::Socket>.
235       The problem is that I<the whole point is to use this with objects
236       that don't have an underlying file/socket descriptor.>.
237       Subclassing L<IO::Handle> will work fine for the OO stuff, and fine with
238       named operators I<if> you C<tie>... but if you just attempt to say:
239
240           $IO = FooHandle->new(&FOO_RDWR, 2);
241           print $IO "Hello!\n";
242
243       you get a warning from Perl like:
244
245           Filehandle GEN001 never opened
246
247       because it's trying to do system-level I/O on an (unopened) file
248       descriptor.  To avoid this, you apparently have to "tie" the handle...
249       which brings us right back to where we started!  At least the
250       IO::WrapTie mixin lets us say:
251
252           $IO = FooHandle->new_tie(&FOO_RDWR, 2);
253           print $IO "Hello!\n";
254
255       and so is not too bad.  ":-)"
256

WARNINGS

258       Remember: this stuff is for doing FileHandle-like I/O on things without
259       underlying file descriptors.  If you have an underlying file
260       descriptor, you're better off just inheriting from IO::Handle.
261
262       Be aware that new_tie() always returns an instance of a kind of
263       IO::WrapTie::Master... it does not return an instance of the I/O class
264       you're tying to!
265
266       Invoking some methods on the master object causes "AUTOLOAD" to
267       delegate them to the slave object... so it looks like you're
268       manipulating a "FooHandle" object directly, but you're not.
269
270       I have not explored all the ramifications of this use of "tie".  Here
271       there be dragons.
272

AUTHOR

274       Eryq (eryq@zeegee.com).  President, ZeeGee Software Inc
275       (http://www.zeegee.com).
276

CONTRIBUTORS

278       Dianne Skoll (dfs@roaringpenguin.com).
279
281       Copyright (c) 1997 Erik (Eryq) Dorfman, ZeeGee Software, Inc. All
282       rights reserved.
283
284       This program is free software; you can redistribute it and/or modify it
285       under the same terms as Perl itself.
286
287
288
289perl v5.38.0                      2023-07-20                    IO::WrapTie(3)
Impressum