File Coverage

blib/lib/Nefarious.pm
Criterion Covered Total %
statement 69 69 100.0
branch 16 18 88.8
condition 5 5 100.0
subroutine 20 20 100.0
pod 0 4 0.0
total 110 116 94.8


line stmt bran cond sub pod time code
1             package Nefarious;
2 10     10   740642 use 5.006; use strict; use warnings;
  10     10   31  
  10     9   270  
  10         37  
  10         2279  
  10         2291  
  9         35  
  9         382  
3 9     9   6475 use Factory::Sub; use Tie::IxHash; our %META;
  9     9   523438  
  9         43  
  9         3808  
  9         27684  
  9         316  
4             our $VERSION = '0.04';
5              
6             BEGIN {
7 9     9   364 tie %META, 'Tie::IxHash';
8             }
9              
10             sub import {
11 7     7   1273 my ($pkg, $nefarious) = @_;
12 7         28 nefarious($nefarious);
13             }
14              
15             sub nefarious {
16 7     7 0 14 my ($nefarious) = @_;
17 7         12 for my $package ( keys %{ $nefarious }) {
  7         29  
18 7         27 parse_meta($package, $nefarious->{$package});
19             }
20 7         60 create_packages();
21             }
22              
23             sub parse_meta {
24 11     11 0 25 my ($name, $package) = @_;
25 11 50       64 $META{$name} = {} if (! $META{$name} );
26 11         399 for my $key (keys %{ $package }) {
  11         40  
27 39         265 my $ref = ref $package->{$key};
28 39 100       113 if (!$ref) {
    100          
    100          
    50          
29 10 100       24 if ($key eq 'EXTENDS') {
30 6         24 $META{$name}{$key} = $package->{$key};
31             } else {
32 4     4   25 $META{$name}{$key} = sub { $package->{$key} };
  4         30  
33             }
34             } elsif ($ref eq 'CODE') {
35 22         77 $META{$name}{$key} = $package->{$key};
36             } elsif ($ref eq 'ARRAY') {
37 3         46 my $factory = Factory::Sub->new();
38 3         40 for my $fact (reverse @{ $package->{$key} }) {
  3         8  
39 10 100   6   278 $factory->add(sub { return $_[0]; }, (ref $fact eq 'ARRAY' ? @{ $fact } : $fact));
  6         446  
  7         25  
40             }
41 3     6   48 $META{$name}{$key} = sub { return $factory->(@_) };
  6         144  
42             } elsif ($ref eq 'HASH') {
43 4         9 $package->{$key}->{EXTENDS} = $name;
44 4         41 parse_meta($key, $package->{$key});
45             }
46             }
47             }
48              
49             sub create_packages {
50 7     7 0 35 for my $pkg ( keys %META ) {
51 14         227 create_package($pkg, $META{$pkg});
52             }
53             }
54              
55              
56             sub create_package {
57 14     14 0 61 my ($name, $package) = @_;
58 14   100     162 my $extends = delete $package->{EXTENDS} || "";
59 14 100       68 $extends = qq|use base '$extends';| if ($extends);
60 14 100 100 9   97 $package->{new} = sub { bless {}, shift } if (! $package->{new} && ! $extends);
  9         58  
61 14         29 my $p = qq|
62             package $name;
63             use strict;
64             use warnings;
65             $extends
66             1;
67             |;
68 14     4   1594 eval $p;
  4     4   34  
  4         8  
  4         199  
  4         20  
  4         15  
  4         185  
69 9     5   3214 no strict 'refs';
  9         37  
  9         2012  
70 5     5   27 no warnings 'redefine';
  5         9  
  5         900  
71 14         40 for my $method (keys %{$package}) {
  14         87  
72 46     62   466 *{"${name}::$method"} = sub { $package->{$method}->(@_) }
  62         1255944  
73 46         158 }
74             }
75              
76             1;
77              
78             __END__