File Coverage

blib/lib/OO/Closures.pm
Criterion Covered Total %
statement 43 54 79.6
branch 13 26 50.0
condition 6 12 50.0
subroutine 8 9 88.8
pod 0 2 0.0
total 70 103 67.9


line stmt bran cond sub pod time code
1             package OO::Closures;
2              
3 1     1   4843 use 5.006;
  1         5  
  1         87  
4              
5 1     1   6 use strict;
  1         3  
  1         44  
6 1     1   6 use warnings;
  1         15  
  1         45  
7 1     1   6 no warnings 'syntax';
  1         1  
  1         138  
8              
9             our $VERSION = '2009110702';
10              
11             sub import {
12 1     1   7 my $my_package = __PACKAGE__;
13 1         4 my $foreign_package = caller;
14 1         2 my $my_sub = 'create_object';
15 1         2 shift;
16 1 50       5 my $foreign_sub = @_ ? shift : $my_sub;
17              
18 1     1   5 no strict 'refs';
  1         2  
  1         1014  
19 1         3 *{"${foreign_package}::$foreign_sub"} = \&{"${my_package}::$my_sub"};
  1         3754  
  1         5  
20             }
21              
22             sub croak {
23 0     0 0 0 require Carp;
24 0         0 goto &Carp::croak;
25             }
26              
27             sub create_object {
28 5     5 0 2690 my ($methods, $ISA, $is_base) = @_;
29              
30             sub {
31 23     23   1144 my ($method, @args) = @_;
32 23         29 my ($call_super, $class);
33              
34 23 100       246 if ($method =~ /^((?:[^:]+|:[^:])*)::(.*)/s) {
35 4         10 $class = $1;
36 4         10 $method = $2;
37             }
38              
39 23 100 100     105 if (exists $methods -> {$method} && !defined $class) {
40 15 100       67 return $methods -> {$method} -> (@args) if
41             ref $methods -> {$method} eq 'CODE';
42 4 100       16 return ${$methods -> {$method}} if
  2         10  
43             ref $methods -> {$method} eq 'SCALAR';
44 2         18 die "Illegal method ($method) in object.\n";
45             }
46              
47 8         12 my @supers;
48 8 100 33     37 if (defined $class && ($class ne 'SUPER' || exists $ISA -> {$class})) {
  4   66     12  
49 4 50       11 unless (exists $ISA -> {$class}) {
50 0         0 croak "No class ($class) found\n";
51             }
52 4         10 @supers = ($ISA -> {$class});
53             }
54             else {@supers = values %$ISA}
55              
56             # Go looking for the method in an inherited object.
57 8         12 foreach my $super (@supers) {
58 8 50       20 return eval {$super -> ($method => @args)} unless $@;
  8         17  
59 0 0         croak $@ unless $@ =~ /^No such method/;
60             }
61              
62 0 0         unless ($is_base) {
63             # This is the base object. So, we'll look for AUTOLOAD.
64 0 0 0       return $methods -> {AUTOLOAD} -> ($method => @args) if exists
65             $methods -> {AUTOLOAD} && !defined $class;
66              
67             # Check %ISA for AUTOLOAD.
68 0           foreach my $super (@supers) {
69 0 0         return eval {$super -> (AUTOLOAD => $method, @args)} unless $@;
  0            
70 0 0         croak $@ unless $@ =~ /^No such method/;
71             }
72             }
73              
74 0           croak "No such method ($method) found";
75             }
76 5         47 }
77              
78              
79             1;
80              
81              
82             __END__