File Coverage

blib/lib/perl5i/1/Meta.pm
Criterion Covered Total %
statement 9 35 25.7
branch 0 12 0.0
condition n/a
subroutine 3 7 42.8
pod 0 4 0.0
total 12 58 20.6


line stmt bran cond sub pod time code
1             package perl5i::1::Meta;
2              
3 1     1   5 use strict;
  1         1  
  1         34  
4 1     1   4 use warnings;
  1         1  
  1         116  
5              
6             # Be very careful not to import anything.
7             require Carp;
8             require mro;
9              
10             require perl5i::1::Meta::Instance;
11             require perl5i::1::Meta::Class;
12              
13             sub UNIVERSAL::mo {
14             return perl5i::1::Meta->new($_[0]);
15             }
16              
17             sub new {
18 0     0 0   my($class, $thing) = @_;
19 0 0         return bless \$thing, ref $thing ? "perl5i::1::Meta::Instance" : "perl5i::1::Meta::Class";
20             }
21              
22             sub ISA {
23 0     0 0   my $class = $_[0]->class;
24              
25 1     1   5 no strict 'refs';
  1         2  
  1         336  
26 0           return @{$class.'::ISA'};
  0            
27             }
28              
29             sub linear_isa {
30 0     0 0   my $self = shift;
31 0           my $class = $self->class;
32              
33             # get_linear_isa() does not return UNIVERSAL
34 0           my @extra;
35 0 0         @extra = qw(UNIVERSAL) unless $class eq 'UNIVERSAL';
36              
37 0           return @{mro::get_linear_isa($class)}, @extra;
  0            
38             }
39              
40              
41             # A single place to put the "method not found" error.
42             my $method_not_found = sub {
43             my $class = shift;
44             my $method = shift;
45              
46             Carp::croak sprintf q[Can't locate object method "%s" via package "%s"],
47             $method, $class;
48             };
49              
50              
51             # caller() will return if its inside an eval, need to skip over those.
52             my $find_method = sub {
53             my $method;
54             my $height = 2;
55             do {
56             $method = (caller($height))[3];
57             $height++;
58             } until( !defined $method or $method ne '(eval)' );
59              
60             return $method;
61             };
62              
63              
64             sub super {
65 0     0 0   my $self = shift;
66 0           my $class = $self->class;
67              
68 0           my $fq_method = $find_method->();
69 0 0         Carp::croak "super() called outside a method" unless $fq_method;
70              
71 0           my($parent, $method) = $fq_method =~ /^(.*)::(\w+)$/;
72              
73 0 0         Carp::croak sprintf qq["%s" is not a parent class of "%s"], $parent, $class
74             unless $class->isa($parent);
75              
76 0           my @isa = $self->linear_isa();
77              
78 0           while(@isa) {
79 0           my $class = shift @isa;
80 0 0         last if $class eq $parent;
81             }
82              
83 0           for (@isa) {
84 0           my $code = $_->can($method);
85 0           @_ = ($$self, @_);
86 0 0         goto &$code if $code;
87             }
88              
89 0           $class->$method_not_found($method);
90             }
91              
92             1;