File Coverage

lib/IO/WrapTie.pm
Criterion Covered Total %
statement 34 56 60.7
branch n/a
condition n/a
subroutine 11 23 47.8
pod 1 2 50.0
total 46 81 56.7


line stmt bran cond sub pod time code
1             # SEE DOCUMENTATION AT BOTTOM OF FILE
2              
3              
4             #------------------------------------------------------------
5             package IO::WrapTie;
6             #------------------------------------------------------------
7             require 5.004; ### for tie
8 6     6   18 use strict;
  6         9  
  6         179  
9 6     6   43 use vars qw(@ISA @EXPORT $VERSION);
  6         8  
  6         275  
10 6     6   19 use Exporter;
  6         6  
  6         578  
11              
12             # Inheritance, exporting, and package version:
13             @ISA = qw(Exporter);
14             @EXPORT = qw(wraptie);
15             $VERSION = "2.111";
16              
17             # Function, exported.
18             sub wraptie {
19 0     0 1 0 IO::WrapTie::Master->new(@_);
20             }
21              
22             # Class method; BACKWARDS-COMPATIBILITY ONLY!
23             sub new {
24 1     1 0 128086 shift;
25 1         10 IO::WrapTie::Master->new(@_);
26             }
27              
28              
29              
30             #------------------------------------------------------------
31             package IO::WrapTie::Master;
32             #------------------------------------------------------------
33              
34 6     6   22 use strict;
  6         3  
  6         145  
35 6     6   23 use vars qw(@ISA $AUTOLOAD);
  6         7  
  6         242  
36 6     6   25 use IO::Handle;
  6         9  
  6         1265  
37              
38             # We inherit from IO::Handle to get methods which invoke i/o operators,
39             # like print(), on our tied handle:
40             @ISA = qw(IO::Handle);
41              
42             #------------------------------
43             # new SLAVE, TIEARGS...
44             #------------------------------
45             # Create a new subclass of IO::Handle which...
46             #
47             # (1) Handles i/o OPERATORS because it is tied to an instance of
48             # an i/o-like class, like IO::Scalar.
49             #
50             # (2) Handles i/o METHODS by delegating them to that same tied object!.
51             #
52             # Arguments are the slave class (e.g., IO::Scalar), followed by all
53             # the arguments normally sent into that class's TIEHANDLE method.
54             # In other words, much like the arguments to tie(). :-)
55             #
56             # NOTE:
57             # The thing $x we return must be a BLESSED REF, for ($x->print()).
58             # The underlying symbol must be a FILEHANDLE, for (print $x "foo").
59             # It has to have a way of getting to the "real" back-end object...
60             #
61             sub new {
62 1     1   2 my $master = shift;
63 1         10 my $io = IO::Handle->new; ### create a new handle
64 1         107 my $slave = shift;
65 1         22 tie *$io, $slave, @_; ### tie: will invoke slave's TIEHANDLE
66 1         4 bless $io, $master; ### return a master
67             }
68              
69             #------------------------------
70             # AUTOLOAD
71             #------------------------------
72             # Delegate method invocations on the master to the underlying slave.
73             #
74             sub AUTOLOAD {
75 1     1   98 my $method = $AUTOLOAD;
76 1         8 $method =~ s/.*:://;
77 1         2 my $self = shift; tied(*$self)->$method(\@_);
  1         7  
78             }
79              
80             #------------------------------
81             # PRELOAD
82             #------------------------------
83             # Utility.
84             #
85             # Most methods like print(), getline(), etc. which work on the tied object
86             # via Perl's i/o operators (like 'print') are inherited from IO::Handle.
87             #
88             # Other methods, like seek() and sref(), we must delegate ourselves.
89             # AUTOLOAD takes care of these.
90             #
91             # However, it may be necessary to preload delegators into your
92             # own class. PRELOAD will do this.
93             #
94             sub PRELOAD {
95 6     6   9 my $class = shift;
96 6         10 foreach (@_) {
97 60     0   1787 eval "sub ${class}::$_ { my \$s = shift; tied(*\$s)->$_(\@_) }";
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     0   0  
  0     1   0  
  0     0   0  
  0     0   0  
  0         0  
  0         0  
  0         0  
  0         0  
  0         0  
  1         107  
  1         6  
  0            
  0            
  0            
  0            
98             }
99             }
100              
101             # Preload delegators for some standard methods which we can't simply
102             # inherit from IO::Handle... for example, some IO::Handle methods
103             # assume that there is an underlying file descriptor.
104             #
105             PRELOAD IO::WrapTie::Master
106             qw(open opened close read clearerr eof seek tell setpos getpos);
107              
108              
109              
110             #------------------------------------------------------------
111             package IO::WrapTie::Slave;
112             #------------------------------------------------------------
113             # Teeny private class providing a new_tie constructor...
114             #
115             # HOW IT ALL WORKS:
116             #
117             # Slaves inherit from this class.
118             #
119             # When you send a new_tie() message to a tie-slave class (like IO::Scalar),
120             # it first determines what class should provide its master, via TIE_MASTER.
121             # In this case, IO::Scalar->TIE_MASTER would return IO::Scalar::Master.
122             # Then, we create a new master (an IO::Scalar::Master) with the same args
123             # sent to new_tie.
124             #
125             # In general, the new() method of the master is inherited directly
126             # from IO::WrapTie::Master.
127             #
128             sub new_tie {
129 0     0     my $self = shift;
130 0           $self->TIE_MASTER->new($self,@_); ### e.g., IO::Scalar::Master->new(@_)
131             }
132              
133             # Default class method for new_tie().
134             # All your tie-slave class (like IO::Scalar) has to do is override this
135             # method with a method that returns the name of an appropriate "master"
136             # class for tying that slave.
137             #
138 0     0     sub TIE_MASTER { 'IO::WrapTie::Master' }
139              
140             #------------------------------
141             1;
142             __END__