File Coverage

blib/lib/Unicode/RecursiveDowngrade.pm
Criterion Covered Total %
statement 34 41 82.9
branch 12 20 60.0
condition 6 8 75.0
subroutine 9 10 90.0
pod 3 3 100.0
total 64 82 78.0


line stmt bran cond sub pod time code
1             package Unicode::RecursiveDowngrade;
2              
3 5     5   13927 use strict;
  5         12  
  5         227  
4 5     5   24 use Carp;
  5         7  
  5         378  
5 5     5   4631 use bytes;
  5         56  
  5         32  
6 5     5   137 use vars qw($DowngradeFunc $VERSION);
  5         9  
  5         436  
7             $VERSION = 0.04;
8              
9             BEGIN {
10 5 50   5   1744 $DowngradeFunc = sub { return defined $_[0] ? pack('C0A*', shift) : undef };
  87         296  
11             }
12              
13 4     4 1 17695 sub new { return bless {}, shift }
14              
15             sub filter {
16 87     87 1 84 my($self, $sub) = @_;
17 87 50       123 if (defined $sub) {
18 0 0       0 if (ref($sub) ne 'CODE') {
19 0         0 carp "Argument of filter() method must be a code-ref";
20 0     0   0 $self->{filter} = sub { shift };
  0         0  
21             }
22             else {
23 0         0 $self->{filter} = $sub;
24             }
25             }
26 87         385 return $self->{filter};
27             }
28              
29             sub downgrade {
30 104     104 1 4756 my($self, $var, $ref) = @_;
31 104   100     296 $ref ||= ref($var);
32 104 100 66     505 if ($ref eq 'ARRAY') {
    100          
    50          
    50          
    100          
    50          
33 8         17 @$var = map { $self->downgrade($_) } @$var;
  31         54  
34             }
35             elsif ($ref eq 'HASH') {
36 32         58 %$var =
37 7         17 map { $self->downgrade($_) => $self->downgrade($var->{$_}) }
38             keys %$var;
39             }
40             elsif ($ref eq 'SCALAR') {
41 0         0 $$var = $self->downgrade($$var);
42             }
43             elsif ($ref eq 'GLOB') {
44 0         0 *var = $self->downgrade(*var);
45             }
46             elsif ($ref ne '' && $ref ne 'CODE') { # maybe blessed reference
47 2         2 my $blessed_class = $ref;
48 2         35 require overload;
49 2         10 my($blessed_ref) =
50             overload::StrVal($var) =~ /^$blessed_class\=(.+?)\(0x[\da-f]+\)$/i;
51 2 50       92 if (length $blessed_ref) {
52 2         6 $var = bless $self->downgrade($var, $blessed_ref), $blessed_class;
53             }
54             }
55             elsif ($ref eq '') {
56 87   50 87   170 my $filter = $self->filter || sub { shift };
  87         193  
57 87         138 $var = $filter->($DowngradeFunc->($var));
58             }
59 104         273 return $var;
60             }
61              
62             1;
63              
64             =head1 NAME
65              
66             Unicode::RecursiveDowngrade - Turn off the UTF-8 flags inside of complex variable
67              
68             =head1 SYNOPSIS
69              
70             use Unicode::RecursiveDowngrade;
71            
72             $rd = Unicode::RecursiveDowngrade->new;
73             $var = {
74             foo => 'bar',
75             baz => [
76             'qux',
77             'quux',
78             ],
79             corge => \$grault,
80             };
81             $unflagged = $rd->downgrade($var);
82              
83             =head1 DESCRIPTION
84              
85             Unicode::RecursiveDowngrade will turn off the UTF-8 flag inside of
86             complex variable in a lump.
87             In spite of your intention, some modules turn it on every elements of
88             returned variable.
89             You may be hard up for turn them off if you don't need any UTF-8 flags
90             in your variable.
91             This module will fix it up easily.
92              
93             Sometime I think about the UTF-8 flag is not stead.
94             But some C based modules will turn it on.
95             For example, C is really simple way to parse XMLs, but
96             this module returns a simple hashref including flagged values.
97             This hashref is very hard to use, isn't it?
98              
99             =head1 METHODS
100              
101             =over 4
102              
103             =item * new
104              
105             C is a constructor method.
106              
107             =item * filter
108              
109             You can set some filter to C accessor. The values of downgraded
110             will be passed this filter function.
111             You have to set a code reference to this accessor.
112             Like this:
113              
114             use Unicode::RecursiveDowngrade;
115             use Unicode::Japanese;
116            
117             $rd = Unicode::RecursiveDowngrade->new;
118             $rd->filter(sub { Unicode::Japanese->new(shift, 'utf8')->euc });
119             $unflagged = $rd->downgrade($var);
120              
121             the passed subref will be called inside C method.
122              
123             =item * downgrade
124              
125             C returns a turned off variable of argument.
126              
127             =back
128              
129             =head1 VARIABLES
130              
131             =over 4
132              
133             =item * $Unicode::RecursiveDowngrade::DowngradeFunc
134              
135             This variable has a downgrade function for C method.
136             You can override the variable for some other way.
137              
138             =back
139              
140             =head1 AUTHOR
141              
142             Koichi Taniguchi Etaniguchi@livedoor.jpE
143              
144             =head1 COPYRIGHT
145              
146             Copyright (c) 2005 Koichi Taniguchi. Japan. All rights reserved.
147              
148             This library is free software; you can redistribute it and/or modify
149             it under the same terms as Perl itself.
150              
151             =head1 SEE ALSO
152              
153             L
154              
155             =cut