File Coverage

blib/lib/Acme/VerySign.pm
Criterion Covered Total %
statement 37 107 34.5
branch 7 32 21.8
condition n/a
subroutine 9 13 69.2
pod 0 3 0.0
total 53 155 34.1


line stmt bran cond sub pod time code
1             package Acme::VerySign;
2              
3 3         24 use overload '""' => "as_string",
4 3     3   98884 fallback => 1;
  3         2764  
5              
6 3     3   359 use Carp;
  3         7  
  3         285  
7 3     3   16 use Devel::Symdump;
  3         12  
  3         78  
8              
9 3     3   15 use strict;
  3         6  
  3         122  
10             #use warnings;
11              
12 3     3   17 use vars qw($AUTOLOAD $VERSION);
  3         5  
  3         805  
13              
14             $VERSION = "1.00";
15              
16             ####################################################################
17             # cargo culted from Symbol::Approx::Sub
18             ####################################################################
19              
20             # List of functions that we _never_ try to match approximately.
21             my @_BARRED = qw(AUTOLOAD BEGIN CHECK INIT DESTROY END);
22             my %_BARRED = (1) x @_BARRED;
23              
24             sub _pkg2file {
25 3     3   6 $_ = shift;
26 3         20 s|::|/|g;
27 3         4852 "$_.pm";
28             }
29              
30             ####################################################################
31              
32             sub import
33             {
34 3     3   25 my $class = shift;
35              
36             # work out who called us
37 3         10 my $pkg = caller(0);
38              
39             # turn off refs while we write to another package namespace
40 3     3   18 no strict "refs";
  3         7  
  3         3845  
41              
42             ####################################################################
43             # cargo culted from Symbol::Approx::Sub
44             ####################################################################
45              
46 3         4 my %param;
47             my %CONF;
48 3 100       17 %param = @_ if @_;
49              
50 3         14 my %defaults = (xform => 'Text::Soundex',
51             match => 'String::Equal',
52             choose => 'Random');
53              
54             # Work out which transformer(s) to use. The valid options are:
55             # 1/ $param{xform} doesn't exist. Use default transformer.
56             # 2/ $param{xform} is undef. Use no transformers.
57             # 3/ $param{xform} is a reference to a subroutine. Use the
58             # referenced subroutine as the transformer.
59             # 4/ $param{xform} is a scalar. This is the name of a transformer
60             # module which should be loaded.
61             # 5/ $param{xform} is a reference to an array. Each element of the
62             # array is one of the previous two options.
63              
64 3 100       12 if (exists $param{xform}) {
65 1 50       4 if (defined $param{xform}) {
66 1         2 my $type = ref $param{xform};
67 1 50       8 if ($type eq 'CODE') {
    50          
    0          
68 0         0 $CONF{xform} = [$param{xform}];
69             } elsif ($type eq '') {
70 1         4 my $mod = "Symbol::Approx::Sub::$param{xform}";
71 1         3 require(_pkg2file($mod));
72 0         0 $CONF{xform} = [\&{"${mod}::transform"}];
  0         0  
73             } elsif ($type eq 'ARRAY') {
74 0         0 foreach (@{$param{xform}}) {
  0         0  
75 0         0 my $type = ref $_;
76 0 0       0 if ($type eq 'CODE') {
    0          
77 0         0 push @{$CONF{xform}}, $_;
  0         0  
78             } elsif ($type eq '') {
79 0         0 my $mod = "Symbol::Approx::Sub::$_";
80 0         0 require(_pkg2file($mod));
81 0         0 push @{$CONF{xform}}, \&{"${mod}::transform"};
  0         0  
  0         0  
82             } else {
83 0         0 croak 'Invalid transformer passed to Acme::VerySign';
84             }
85             }
86             } else {
87 0         0 croak 'Invalid transformer passed to Acme::VerySign';
88             }
89             } else {
90 0         0 $CONF{xform} = [];
91             }
92             } else {
93 2         6 my $mod = "Symbol::Approx::Sub::$defaults{xform}";
94 2         7 require(_pkg2file($mod));
95 0           $CONF{xform} = [\&{"${mod}::transform"}];
  0            
96             }
97              
98             # Work out which matcher to use. The valid options are:
99             # 1/ $param{match} doesn't exist. Use default matcher.
100             # 2/ $param{match} is undef. Use no matcher.
101             # 3/ $param{match} is a reference to a subroutine. Use the
102             # referenced subroutine as the matcher.
103             # 4/ $param{match} is a scalar. This is the name of a matcher
104             # module which should be loaded.
105              
106 0 0         if (exists $param{match}) {
107 0 0         if (defined $param{match}) {
108 0           my $type = ref $param{match};
109 0 0         if ($type eq 'CODE') {
    0          
110 0           $CONF{match} = $param{match};
111             } elsif ($type eq '') {
112 0           my $mod = "Symbol::Approx::Sub::$param{match}";
113 0           require(_pkg2file($mod));
114 0           $CONF{match} = \&{"${mod}::match"};
  0            
115             } else {
116 0           croak 'Invalid matcher passed to Symbol::Approx::Sub';
117             }
118             } else {
119 0           $CONF{match} = undef;
120             }
121             } else {
122 0           my $mod = "Symbol::Approx::Sub::$defaults{match}";
123 0           require(_pkg2file($mod));
124 0           $CONF{match} = \&{"${mod}::match"};
  0            
125             }
126              
127              
128             ####################################################################
129              
130             # install the AUTOLOAD method
131 0           *{"${pkg}::AUTOLOAD"} = sub {
132 0     0     Acme::VerySign->new($AUTOLOAD =~ /^(.*)::(.*)$/, %CONF);
133             }
134 0           }
135              
136             {
137             my $pkg;
138             my $subname;
139              
140             sub new
141             {
142 0     0 0   my $class = shift;
143 0           $pkg = shift;
144 0           my $sub = $subname = shift;
145 0           my %CONF = @_;
146              
147             ####################################################################
148             # code cargo culted from Symbol::Approx::Sub
149             ####################################################################
150              
151             # Get a list of all of the subroutines in the current package
152             # using the get_subs function from GlobWalker.pm
153             # Note that we deliberately omit function names that exist
154             # in the %_BARRED hash
155 0           my (@subs, @orig);
156 0           my $sym = Devel::Symdump->new($pkg);
157 0           @orig = @subs = grep { ! $_BARRED{$_} }
  0            
158 0           map { s/${pkg}:://; $_ }
  0            
159 0           grep { defined &{$_} } $sym->functions($pkg);
  0            
160              
161             # Transform all of the subroutine names
162 0           foreach (@{$CONF{xform}}) {
  0            
163 0 0         croak "Invalid transformer passed to Acme::VerySign\n"
164             unless defined &$_;
165 0           ($sub, @subs) = $_->($sub, @subs);
166             }
167              
168             # Call the subroutine that will look for matches
169             # The matcher returns a list of the _indexes_ that match
170 0           my @match_ind;
171 0 0         if ($CONF{match}) {
172 0           croak "Invalid matcher passed to Acme::VerySign\n"
173 0 0         unless defined &{$CONF{match}};
174 0           @match_ind = $CONF{match}->($sub, @subs);
175             } else {
176 0           @match_ind = (0..$#subs);
177             }
178              
179 0           @orig = @orig[@match_ind];
180              
181              
182             ####################################################################
183              
184             # unique that array
185 0           my %orig = map { $_ => 1 } @orig;
  0            
186 0           my $this = bless [keys %orig], $class;
187 0           return $this;
188             }
189              
190 0     0 0   sub as_string { "64.94.110.11" }
191              
192             sub buy
193             {
194 0     0 0   my $this = shift;
195 0 0         die "No matching subroutines!" unless defined $this->[0];
196 3     3   47 no strict 'refs';
  3         7  
  3         301  
197 0           *{"${pkg}::${subname}"} = *{"${pkg}::".$this->[0]}{CODE};
  0            
  0            
198             }
199              
200             }
201              
202             1;
203              
204             __END__