| 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__ |