File Coverage

blib/lib/Class/Light.pm
Criterion Covered Total %
statement 60 63 95.2
branch 10 16 62.5
condition 4 12 33.3
subroutine 11 12 91.6
pod 0 1 0.0
total 85 104 81.7


line stmt bran cond sub pod time code
1             package Class::Light;
2             # Copyright (c) 2009 Christopher Davaz. All rights reserved.
3             # This program is free software; you can redistribute it and/or
4             # modify it under the same terms as Perl itself.
5             #
6             # Documentation at the __END__
7              
8 1     1   746 use strict;
  1         2  
  1         31  
9 1     1   4 use warnings;
  1         2  
  1         27  
10 1     1   5 use vars qw($VERSION);
  1         3  
  1         62  
11 1     1   5 use Carp;
  1         2  
  1         148  
12              
13             $VERSION = "0.01003";
14              
15             sub new {
16 1     1 0 22 my $class = shift;
17              
18 1 50       5 croak "Attempted instantiation of abstract class " + __PACKAGE__
19             if $class eq __PACKAGE__;
20              
21 1         3 my $super = $class;
22 1         1 my @super;
23              
24             # Find all super classes and add them to @super in hierarchical order.
25 1     1   5 no strict 'refs';
  1         5  
  1         83  
26 1         6 while ($super ne __PACKAGE__) {
27 1         4 unshift @super, $super;
28 1         2 $super = ${$super . "::ISA"}[0];
  1         8  
29             }
30              
31 1         3 my $self = {};
32 1         2 bless $self, $class;
33              
34 1         4 for (@super) {
35 1         4 my $init = $_ . "::_init";
36 1 50       9 &$init($self, @_) if exists &$init;
37             }
38 1     1   4 use strict 'refs';
  1         2  
  1         311  
39              
40 1         13 return $self;
41             }
42              
43             # Subclasses should implement their own _init method.
44             sub init;
45              
46             our $AUTOLOAD;
47             sub AUTOLOAD {
48 6     6   2029 my ($pkg, $method) = ($AUTOLOAD =~ /(.+)::(.+)/);
49 6         29 my ($type, $attr) = ($method =~ /^(get|set)_?(.*)/);
50              
51             # We only handle methods that match the pattern /^(get|set)_?(.*)/
52 6 50 33     38 croak "Unknown method: $AUTOLOAD" unless $type && $attr;
53              
54 6         10 my $origAttr = $attr;
55 6         11 $attr = lcfirst $attr;
56              
57             # Don't allow calls such as "getattr", see documentation for details.
58 6 50 33     22 if ($method eq $type . $attr && $origAttr eq $attr) {
59 0         0 croak "Unknown method: $AUTOLOAD";
60             }
61              
62             # Disallow access to private members
63 6 50 33     137 unless ($type && $attr !~ /^_/ && exists $_[0]->{$attr}) {
      33        
64 0         0 croak "Unknown method: $AUTOLOAD";
65             }
66              
67             # We want to check if an alternative form of invocation is available
68             # and if it is make an alias for that method instead of calling the
69             # automatically generated one.
70 6         30 my (@form) = (
71             $pkg . "::" . $type . ucfirst $origAttr,
72             $pkg . "::" . $type . "_" . $origAttr,
73             $pkg . "::" . $type . "_" . $attr
74             );
75              
76 1     1   5 no strict 'refs';
  1         5  
  1         382  
77 6         12 for (@form) {
78 10 100       36 if (exists &$_) {
79 4         11 *{$AUTOLOAD} = \&$_;
  4         15  
80 4         6 goto &{$AUTOLOAD};
  4         18  
81             }
82             }
83              
84 2 100       162 if ($type =~ /^get/) {
    50          
85 1     6   7 *{$AUTOLOAD} = sub { return $_[0]->{$attr} };
  1         6  
  6         47  
86             }
87             elsif ($type =~ /^set/) {
88 1         4 *{$AUTOLOAD} = sub {
89 3     3   21 my $old = $_[0]->{$attr};
90 3         8 $_[0]->{$attr} = $_[1];
91 3         7 return $old;
92             }
93 1         7 }
94              
95 2         4 goto &{$AUTOLOAD};
  2         12  
96             }
97              
98 0     0     sub DESTROY {}
99              
100             1;
101             __END__