File Coverage

blib/lib/Object/Prototype.pm
Criterion Covered Total %
statement 53 54 98.1
branch 10 16 62.5
condition n/a
subroutine 11 11 100.0
pod 3 3 100.0
total 77 84 91.6


line stmt bran cond sub pod time code
1             package Object::Prototype;
2              
3             # $Id: Prototype.pm,v 0.2 2007/04/07 01:57:59 dankogai Exp dankogai $
4 3     3   29012 use 5.008001;
  3         11  
  3         116  
5 3     3   16 use strict;
  3         5  
  3         83  
6 3     3   13 use warnings;
  3         10  
  3         84  
7 3     3   16 use Carp;
  3         5  
  3         284  
8 3     3   17 use Scalar::Util qw(refaddr);
  3         5  
  3         343  
9 3     3   4091 use Storable ();
  3         12986  
  3         2124  
10              
11             our $VERSION = sprintf "%d.%02d", q$Revision: 0.2 $ =~ /(\d+)/g;
12             our $DEBUG = 0;
13             my %constructor_of;
14             my %prototype_of;
15              
16             sub new($$;$) {
17 17     17 1 5069 my $class = shift;
18 17         25 my $constructor = shift;
19 17         1232 my $self = Storable::dclone($constructor);
20 17         52 my $id = refaddr $self;
21 17         46 $constructor_of{$id} = $constructor;
22 17         34 $prototype_of{$id} = {};
23 17         36 bless $self => $class;
24 17         19 for my $method ( keys %{ $_[0] } ) {
  17         70  
25 24         61 $self->prototype( $method, $_[0]->{$method} );
26             }
27 17         59 return $self;
28             }
29              
30             sub prototype($$;$) {
31 29     29 1 3058 my $self = shift;
32 29         46 my $id = refaddr $self;
33 29         36 my $method = shift;
34 29 50       98 $prototype_of{$id}{$method} = shift if @_;
35 29         77 return $prototype_of{$id}{$method};
36             }
37              
38             sub constructor($) {
39 2     2 1 487 my $self = shift;
40 2         8 my $id = refaddr $self;
41 2         11 return $constructor_of{$id}
42             }
43              
44             sub DESTROY {
45 17     17   1049 my $id = refaddr shift;
46 17 50       39 carp "DESTROY: $id" if $DEBUG;
47 17         29 delete $constructor_of{$id};
48 17         335 delete $prototype_of{$id};
49             }
50              
51             sub AUTOLOAD {
52 54     54   19061 my $self = shift;
53 54         81 my $method = our $AUTOLOAD;
54 54         238 $method =~ s/.*:://o;
55 54         124 my $id = refaddr $self;
56 54 50       120 warn "$id -> $method" if $DEBUG;
57 54         101 my $code = $prototype_of{$id}{$method};
58 54 100       897 return $self->$code(@_) if $code;
59 26         71 while ( my $constructor = $constructor_of{$id} ) {
60 79 50       140 warn "$constructor -> $method" if $DEBUG;
61 79         138 $id = refaddr $constructor;
62 79 100       233 $code = ref $constructor eq ref $self
63             ? $prototype_of{$id}{$method} # Prototypal
64             : $constructor->can($method); # Classical Perl Obj.
65 77 100       256 return $self->$code(@_) if $code;
66             }
67 0 0         confess "unknown method : $method" if !$code;
68             }
69              
70             1;
71             __END__