File Coverage

blib/lib/My/Object.pm
Criterion Covered Total %
statement 74 75 98.6
branch 17 18 94.4
condition 4 6 66.6
subroutine 15 15 100.0
pod 0 1 0.0
total 110 115 95.6


line stmt bran cond sub pod time code
1 2     2   51238 use strict;
  2         5  
  2         87  
2 2     2   11 use warnings;
  2         4  
  2         158  
3              
4             package My::Object;
5             BEGIN {
6 2     2   8 *VERSION = \'0.02';
7 2         265 *import = \&My::Object::Import::import;
8             }
9              
10             our %PROTO;
11              
12             sub BUILD {
13 2     2 0 8 my ($obj, %ini) = @_;
14 2         40 @$obj{keys %ini} = values %ini;
15             }
16              
17             package My::Object::Import;
18 2     2   11 use Carp qw(carp);
  2         4  
  2         178  
19 2     2   2066 use Module::Loaded qw(is_loaded mark_as_loaded);
  2         1486  
  2         142  
20 2     2   16 use Scalar::Util qw(refaddr);
  2         4  
  2         241  
21              
22 2     2   12 no strict 'refs';
  2         3  
  2         57  
23 2     2   9 no warnings 'once';
  2         4  
  2         1722  
24              
25             sub create_accessor {
26 7     7   12 my ($name) = @_;
27 7     17   37 return sub : lvalue { shift->{$name} };
  17         199  
28             }
29              
30             sub create_NEW {
31 5     5   13 my ($pkg) = @_;
32             return sub {
33 4 100 33 4   386 my $suffix = @_ ? '_'.($_[0] =~ /([^:]+)$/ && $1) : '';
34 4         6 my $builder = \&{$pkg.'::BUILD'.$suffix};
  4         20  
35             return sub {
36 4     4   19 my $proto = \%{$pkg.'::PROTO'};
  4         23  
37 9 100       62 my $obj = bless { map {
38 4         19 ($_, s/^-// ? $proto->{"-$_"}->() : $proto->{$_} )
39             } keys %$proto }, $pkg;
40              
41 4         28 $builder->($obj, @_);
42 4         17 return $obj;
43 4         2271 };
44 5         27 };
45             }
46              
47             sub import {
48 7     7   5792 my ($parent, $defs) = @_;
49 7         15 my $pkg = caller;
50              
51 7         19 my $proto = \%{$pkg.'::PROTO'};
  7         37  
52 7         8 @{$proto}{keys %{$parent.'::PROTO'}} = values %{$parent.'::PROTO'};
  7         14  
  7         16  
  7         27  
53 7         20 @{$proto}{keys %$defs} = values %$defs;
  7         15  
54              
55 7         12 *{$pkg.'::import'} = \&My::Object::Import::import;
  7         26  
56 5         24 *{$pkg.'::NEW'} = create_NEW($pkg)
  7         40  
57 7 100       9 unless exists &{$pkg.'::NEW'};
58              
59 7         9 for my $name (keys %{$parent.'::'}) {
  7         27  
60 45 100 100     46 next if !exists &{$parent.'::'.$name}
  45         236  
61             || $name =~ /^(?:NEW|import)$/;
62              
63 12 100       12 if (defined &{$pkg.'::'.$name}) {
  12 100       61  
  10         29  
64 2         8 next if refaddr(\&{$pkg.'::'.$name})
  2         11  
65 2 50       3 == refaddr(\&{$parent.'::'.$name});
66 0         0 carp "Subroutine $name redefined in $pkg";
67             }
68             elsif (exists &{$pkg.'::'.$name}) {}
69 9         10 else { *{$pkg.'::'.$name} = \&{$parent.'::'.$name} }
  9         41  
  9         21  
70             }
71              
72 7         22 for my $name (keys %$proto) {
73 9         19 $name =~ s/^-//;
74 7         37 *{$pkg.'::'.$name} = create_accessor($name)
  9         38  
75 9 100       11 unless exists &{$pkg.'::'.$name};
76             }
77              
78 7 100       25 mark_as_loaded($pkg)
79             unless is_loaded($pkg);
80             }
81              
82             1;
83             __END__