File Coverage

blib/lib/Acme/Octarine.pm
Criterion Covered Total %
statement 35 37 94.5
branch 4 6 66.6
condition 1 3 33.3
subroutine 10 10 100.0
pod 1 2 50.0
total 51 58 87.9


line stmt bran cond sub pod time code
1             package Acme::Octarine;
2              
3 2     2   59906 use 5.005;
  2         7  
  2         75  
4 2     2   12 use strict;
  2         4  
  2         71  
5              
6 2     2   1866 use Acme::Colour;
  2         45840  
  2         13  
7              
8 2     2   28857 use vars qw($VERSION @Acmes);
  2         5  
  2         147  
9             $VERSION = '0.02';
10              
11             # I need some hooks in Acme::Colour's constructor. But as we all know cut and
12             # paste is bad. So we are good and don't do that:
13              
14 2     2   14 use B::Deparse;
  2         6  
  2         53  
15 2     2   1814 use PadWalker 'closed_over';
  2         19475  
  2         1075  
16              
17             # Frustratingly, he uses a package lexical %r, which foils a simple re-eval of
18             # the deparsed method code.
19             my $deparse = B::Deparse->new("-sC");
20             my $body = $deparse->coderef2text(\&Acme::Colour::new);
21             my $r = closed_over(\&Acme::Colour::new)->{'%r'};
22              
23             # Add a my $sub; declaration at the top level
24             $body =~ s/([ \t]+)(bless)/$1my \$sub;\n$1$2/ or die $body;
25             # If colour is defined, look it up in the specials hash
26             $body =~ s/
27             ([ \t]+) # Must get the indent correct
28             (unless[ \t]*\(exists[ \t]*\$r)({\$colour})\)
29             /$1\$sub = \$Acme::Colour::specials{\$colour};
30             $1$2->$3 or defined \$sub)/sx or die $body;
31              
32             # If a specials subroutine was found, call it instead of making a simple return
33             $body =~ s/
34             ([ \t]+) # Most get the indent correct
35             (return\s*(\$\w+))\s*;?\s* # Probably the last line of the subroutine.
36             }/
37             $1$2 unless \$sub; # default behaviour unless we are a special colour
38             $1&\$sub($3);
39             }/sx or die $body;
40              
41             {
42             # Turn off warnings.
43             local $^W;
44 2 50 33 2 1 18 eval "sub Acme::Colour::new $body";
  2 50   2   3  
  2 100   2   69  
  2         12  
  2         4  
  2         468  
  2         2609  
  2         6  
  2         5  
  2         6  
  2         7  
  2         6  
  2         13  
  0         0  
  2         48  
  0         0  
  2         10  
  1         5  
45             die if $@;
46             }
47              
48             require CPANPLUS::Backend;
49             # Currently CPANPLUS only supports one backend per program.
50              
51             my $cp = CPANPLUS::Backend->new;
52             $cp->configure_object()->set_conf(verbose=>0);
53             @Acmes = map {$_->name} $cp->search(type => 'module',
54             allow => [qr/^Acme::/]);
55              
56             sub random_acme_module {
57 3     3 0 6034 $Acmes[rand @Acmes];
58             }
59              
60              
61             $Acme::Colour::specials{octarine} = $Acme::Colour::specials{Octarine} =
62             sub {
63             my $object = shift;
64             $object->{colour} = 'black';
65             my $rv = $cp->install( modules => [ &random_acme_module ]);
66             # Ooops. Don't worry if it's OK
67             return $object;
68             };
69              
70             1;
71             __END__