File Coverage

blib/lib/Tie/Util.pm
Criterion Covered Total %
statement 115 117 98.2
branch 90 98 91.8
condition 22 35 62.8
subroutine 15 15 100.0
pod 7 7 100.0
total 249 272 91.5


line stmt bran cond sub pod time code
1             package Tie::Util;
2              
3 1     1   17588 use 5.008;
  1         4  
  1         61  
4              
5             $VERSION = '0.04';
6              
7             # B doesn't export this. I *hope* it doesn't change!
8 1     1   7 use constant SVprv_WEAKREF => 0x80000000; # from sv.h
  1         2  
  1         89  
9              
10 1     1   5 use Exporter 5.57 'import';
  1         19  
  1         31  
11 1     1   4 use Scalar::Util 1.09 qw 'reftype blessed weaken';
  1         15  
  1         786  
12              
13             @EXPORT = qw 'is_tied weak_tie weaken_tie is_weak_tie tie tied';
14             @EXPORT_OK = 'fix_tie';
15             %EXPORT_TAGS = (all=>[@EXPORT,@EXPORT_OK]);
16              
17             {
18             my ($ref, $class);
19             sub _underload($) {
20 221     221   304 $ref = shift;
21 221         599 my $type = reftype $ref;
22             # This assumes that no one is overloading without loading
23             # overload.pm. I suppose I could change this to call
24             # UNIVERSAL::can($ref, "($sigil\{}") (at the risk of trig-
25             # ering negative reactions from OO-purists perusing
26             # this code :-).
27 221 100 66     1347 if(defined blessed $ref && $INC{'overload.pm'}) {
28 170 100 66     894 my $sigil = $type eq 'GLOB' || $type eq 'IO' ? '*'
    100          
    100          
29             :$type eq 'HASH' ? '%'
30             :$type eq 'ARRAY' ? '@'
31             : '$';
32 170 50       598 if(defined overload::Method($ref,"$sigil\{}")) {
33 170         8669 $class = ref $ref;
34 170         317 bless $ref;
35             }
36             }
37 221         5311 return $ref;
38             }
39             sub _restore() {
40 221 100   221   658 defined $class and bless $ref, $class;
41 221         3615 undef $ref, undef $class
42             }
43             }
44              
45             sub expand($) {
46             local *_ = \do{my $x = shift};
47             my $done_type;
48             s<<<<(.*?)>>>><
49             my $code = $1;
50             my $type_decl = '';
51             unless($done_type++) {
52             $code =~ /\*(?:(\$\w+)|\{(.*?)})/;
53             $type_decl = "my \$type = reftype " . ($1||$2);
54             }
55             my $subst = "
56             $type_decl;
57             if(\$type eq 'GLOB' || \$type eq 'IO') {
58             $code
59             } elsif(\$type eq 'HASH') {
60             ";
61             (my $copy = $code) =~ y @*@%@;
62             $subst .= qq!
63             $copy
64             } elsif(\$type eq 'ARRAY') {
65             !;
66             ($copy = $code) =~ y ~*~@~;
67             $subst .= "
68             $copy
69             } else {
70             ";
71             $code =~ y&*&$&;
72             "$subst$code}";
73             >gse;
74             #local $SIG{__WARN__} = sub { warn shift;die $_ };
75 1 100 66 1 1 12 eval "$_}1" or die $@, "\n", $_;
  1 100 66 97 1 2  
  1 100 66 29 1 85  
  97 100 66 42 1 188  
  97 100 50 14   233  
  97 100 50     334  
  97 100 50     528  
  26 100 100     107  
  13 100 66     55  
  14 100 66     60  
  44 100       150  
  43 100       98  
  43 100       70  
  43 100       234  
  12 100       93  
  6 100       49  
  6 100       43  
  19 100       135  
  43 100       121  
  43 50       680  
  29 50       1547  
  22 100       80  
  22 100       92  
  22 100       140  
  6 100       9  
  6 100       36  
  3 100       5  
  3 100       25  
  3 100       5  
  3 100       22  
  10 100       14  
  10 100       54  
  14 50       27  
  14 100       34  
  14 100       44  
  14 100       48  
  14         118  
  14         235  
  0         0  
  42         1825  
  42         110  
  42         67  
  42         124  
  42         251  
  10         66  
  5         36  
  6         52  
  21         527  
  42         727  
  42         131  
  42         138  
  14         56  
  14         28  
  14         49  
  14         101  
  4         13  
  2         5  
  2         6  
  6         14  
  14         36  
  0         0  
  14         15  
  14         80  
  14         80  
  4         21  
  2         14  
  2         13  
  6         37  
  14         49  
76             #warn $_;
77             }
78              
79             # This is what I first intended, but I realised that a to:: package allowed
80             # a weak tie as well, without requiring Yet Another function.
81             #expand<<'}';
82             #sub tie_to (\[%$@*]$) {
83             # my ($var, $obj) = @_;
84             # my $class = _underload $var;
85             # <<>>
86             # _restore;
87             # $obj
88             #}
89              
90             #*TIEARRAY = *TIESCALAR = *TIEHANDLE = *TIEHASH = sub { $_[1] };
91 34     34   1048 *to'TIEARRAY = *to'TIESCALAR = *to'TIEHANDLE = *to'TIEHASH = sub { $_[1] };
92              
93              
94             # :lvalue makes the following sub return the same scalar, as is evidenced
95             # by the following one-liner:
96             #
97             # perl -MScalar::Util=refaddr -le 'print refaddr \sub:lvalue { \
98             # print refaddr \my $x; $x}->()'
99             #
100             # (Remove the :lvalue and you get two different refaddrs.)
101              
102             expand<<'}';
103             sub tie(\[%$@*]$@):lvalue {
104             my($var,$class,@args) = @_; _underload $var;
105             #warn "$class: $args[0]";
106             my $ref_thereto;
107             <<<$ref_thereto =
108             \tie *$var, $class,
109             $class eq 'to'
110             ? $dummy ||= bless\my $dummy
111             : @args;>>>
112             _restore;
113             $$ref_thereto = $args[0], if $class eq 'to';
114             $$ref_thereto;
115             }
116              
117             expand<<'}';
118             sub is_tied (\[%$@*]) {
119             my ($var) = @_;
120             my $class = _underload $var;
121             <<>>
122             # If tied returns undef, it might still be tied, in which case all
123             # tie methods will die.
124             local *@;
125             eval {
126             if( $type eq 'GLOB' || $type eq 'IO' ){
127             no warnings 'unopened';
128             ()= tell $var
129             } elsif($type eq 'HASH') {
130             #()= %$var # We can't use this, because it might
131             # be an untied hash with a stale tied
132             # element, and we could get a
133             # false positive.
134             ()= scalar keys %$var
135             } elsif($type eq 'ARRAY') {
136             #()= @$var # same here
137             ()= $#$var;
138             } else {
139             my $dummy = $$var
140             }
141             };
142             _restore;
143             return !!$@;
144             }
145              
146             sub weak_tie(\[%@$*]$@):lvalue{
147 9     9 1 417 my($var,$class,@args) = @_;
148 9         217 my $ref =\ &tie($var, $class, @args);
149 9         23 weaken $$ref;
150 9         16 $$ref;
151             }
152              
153             expand<<'}';
154             sub weaken_tie(\[%@$*]){
155             my $var = _underload shift;
156             my $obj;
157             <<<$obj = CORE::tied *$var;>>>
158             if(!defined $obj) {
159             _restore, return
160             }
161             # I have to re-tie it, since 'weaken tied' doesn't work.
162             local *{ref($obj).'::UNTIE'};
163             << $obj>>>;
164             _restore, return;
165             }
166              
167             expand<<'}';
168             sub is_weak_tie(\[%@$*]){
169             return undef unless &is_tied($_[0]);
170             _underload $_[0];
171             <<<
172             _restore,return !1 if not defined reftype CORE::tied *{$_[0]};
173             >>>
174              
175             # We have to use B here because 'isweak tied' fails.
176              
177             # From pp_sys.c in the perl source code:
178             # /* For tied filehandles, we apply tiedscalar magic to the IO
179             # slot of the GP rather than the GV itself. AMS 20010812 */
180             my $thing = shift;
181             $type eq 'GLOB' and $thing = *$thing{IO};
182             _restore;
183              
184             exists & svref_2object or require(B), B->import('svref_2object');
185             for(svref_2object($thing)->MAGIC) {
186             $_->TYPE =~ /^[qPp]\z/ and
187             return !!($_->OBJ->FLAGS & SVprv_WEAKREF);
188             }
189             die "Tie::Util internal error: This tied variable has no tie magic! Bug reports welcome.";
190             }
191              
192             sub tied(\[%@$*]):lvalue{
193 46 50   46 1 2620 return undef unless &is_tied($_[0]);
194              
195             # From pp_sys.c in the perl source code:
196             # /* For tied filehandles, we apply tiedscalar magic to the IO
197             # slot of the GP rather than the GV itself. AMS 20010812 */
198 46         69 my $thing = shift;
199 46         79 _underload $thing;
200 46 100       156 reftype $thing eq 'GLOB' and $thing = *$thing{IO};
201 46         69 _restore;
202              
203 46 100       129 exists & svref_2object or require(B), B->import('svref_2object');
204 46         368 for(svref_2object($thing)->MAGIC) {
205 54 100       531 $_->TYPE =~ /^[qPp]\z/ and
206             $thing = $_->OBJ->object_2svref;
207             }
208 46 50       136 $thing or die "Tie::Util internal error: " .
209             "This tied variable has no tie magic! Bug reports welcome.";
210 46         248 $$thing;
211             }
212              
213             sub fix_tie($):lvalue {
214 2     2 1 1372 for my $tie ($_[0]) {
215             return
216 2 50 33     21 unless ref \$tie eq REF and defined( my $tie_obj = CORE::tied $tie);
217 2         6 my $pkg = ref $tie_obj;
218 2 50       8 length $pkg or $pkg = $tie_obj;
219 2         3 local *{"$pkg:\:STORE"};
  2         14  
220 2         3 undef *{"$pkg:\:STORE"};
  2         9  
221 2         4 eval { $tie = undef }
  2         44  
222             }
223 2         8 $_[0];
224             }
225              
226             undef *expand;
227              
228             ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~!()__END__()!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
229              
230             =head1 NAME
231              
232             Tie::Util - Utility functions for fiddling with tied variables
233              
234             =head1 VERSION
235              
236             Version 0.04 (beta)
237              
238             =head1 SYNOPSIS
239              
240             use Tie::Util;
241            
242             use Tie::RefHash;
243             tie %hash, 'Tie::RefHash';
244            
245             $obj = tied %hash;
246             tie %another_hash, to => $obj; # two hashes now tied to the same object
247             Tie::Util::tie @whatever, to => "MyClass"; # tie @whatever to a class
248            
249             is_tied %hash; # returns true
250            
251             $obj = weak_tie %hash3, 'Tie::RefHash';
252             # %hash3 now holds a weak reference to the Tie::RefHash object.
253            
254             weaken_tie %another_hash; # weaken an existing tie
255            
256             is_weak_tie %hash3; # returns true
257             is_weak_tie %hash; # returns false but defined
258             is_weak_tie %hash4; # returns undef (not tied)
259              
260              
261             =head1 DESCRIPTION
262              
263             This module provides a few subroutines for examining and modifying
264             tied variables, including those that hold weak references to the
265             objects to which they are tied (weak ties).
266              
267             It also provides tie constructors in the C namespace, so that you can
268             tie variables to existing objects, like this:
269              
270             tie $var, to => $obj;
271             weak_tie @var, to => $another_obj; # for a weak tie
272              
273             It also allows one to tie a variable to a package, instead of an object
274             (see below).
275              
276             =for comment
277             This is how it would read if perl let me override tie
278             , if the C function is imported (which is done by default).
279              
280             =head1 FUNCTIONS
281              
282             All the following functions are exported by default, except for C.
283             You can choose to
284             import only a few, with C, or none at
285             all, with C.
286              
287             =over 4
288              
289             =item is_tied [*%@$]var
290              
291             Similar to the built-in L function, but it returns a
292             simple scalar.
293              
294             With this function you don't have to worry about whether the object to
295             which a variable is tied overloads its booleanness (like L
296             I), so you can simply write C instead
297             of C.
298              
299             Furthermore, it will still return true if it is a weak tie that has gone
300             stale (the object to which it was tied [without holding a reference count]
301             has lost all other references, so the variable is now tied to C),
302             whereas C returns C in such cases.
303              
304             =item tie [*%@$]var, $package, @args
305              
306             =item &tie( \$var, $package, @args );
307              
308             perl did not allow the built-in to be overridden until version 5.13.3, so,
309             for older perls, you have to
310             call this with the C prefix or use the C<&tie(...)> notation.
311              
312             This is just like the built-in function except that, when called with
313             'to' as the package, it allows you to tie the variable to I
314             (well,
315             any scalar at least). This is
316             probably only useful for tying a variable to a package, as opposed to an
317             object. (Believe it or not, it's just pure Perl; no XS trickery.)
318              
319             Otherwise the behaviour is identical to the core function.
320              
321             =item weak_tie [*%@$]var, $package, @args
322              
323             Like perl's L function, this calls C<$package>'s tie
324             constructor, passing
325             it the C<@args>, and ties the variable to the returned object. But the tie
326             that it creates is a weak one, i.e., the tied variable does not hold a
327             reference count on the object.
328              
329             Like C, above, it lets you tie the variable to anything, not just an
330             object.
331              
332             =item weaken_tie [*%@$]var
333              
334             This turns an existing tie into a weak one.
335              
336             =item is_weak_tie [*%@$]var
337              
338             Returns a defined true or false, indicating whether a tied variable is
339             weakly tied. Returns C if the variable is not tied.
340              
341             NOTE: This used to return true for a variable tied to C. Now (as of
342             version 0.02) it returns false, because the tie does not actually hold a
343             weak reference; it holds no reference at all.
344              
345             =item tied [*%@$]var
346              
347             =item &tied( \$var )
348              
349             Like perl's L function, this returns what the variable
350             is tied to, but, unlike the built-in, it returns the actual scalar that the
351             tie uses (instead of copying it), so you can, for instance, check to see
352             whether the variable is
353             tied to a tied variable with C.
354              
355             As with C, you need to use the C prefix or the ampersand
356             form if your perl
357             version is less than 5.13.3.
358              
359             =item fix_tie (scalar lvalue expression)
360              
361             This provides a work-around for a bug in perl that was introduced in 5.8.9
362             and 5.10.0, but was fixed in 5.13.2: If you assign a reference to a
363             tied scalar variable, some operators will operate on that reference,
364             instead of
365             calling C and using its return value.
366              
367             If you assign a reference to a tied variable, or a value that I be a
368             reference to a variable that I be tied, then you can 'fix' the tie
369             afterwards by called C on it. C is an lvalue function
370             that returns its first argument after fixing it, so you can replace code
371             like
372              
373             ($var = $value) =~ s/fror/dwat/;
374              
375             with
376              
377             fix_tie( $var = $value ) =~ s/fror/dwat/;
378              
379             =back
380              
381             =head1 THE to NAMESPACE
382              
383             Tie::Util installs tie constructors in the 'to' package to work its magic.
384             If anyone else wants to release a module named 'to', just let me know and
385             I'll give you comaint status, as long as you promise not to break
386             Tie::Util!
387              
388             =head1 PREREQUISITES
389              
390             perl 5.8.0 or later
391              
392             Exporter 5.57 or later
393              
394             Scalar::Util 1.09 or later
395              
396             =head1 BUGS
397              
398             =over 4
399              
400             =item *
401              
402             This module does not provide a single function to access the information
403             obscured by
404             a tie. For
405             that, you can simply untie a variable, access its contents, and re-tie it
406             (which is fairly trivial with the functions this module already provides).
407              
408             =back
409              
410             Please report bugs at L or send email to
411             .
412              
413             =head1 AUTHOR & COPYRIGHT
414              
415             Copyright (C) 2007-14 Father Chrysostomos
416             [dot] org>
417              
418             This program is free software; you may redistribute it and/or modify
419             it under the same terms as perl.
420              
421             =head1 SEE ALSO
422              
423             The L and L functions in the
424             L man page.
425              
426             The L man page.
427              
428             L's L function
429              
430             The L module.
431              
432             L, for which I wrote two of these functions.