File Coverage

lib/Class/Dot/Object.pm
Criterion Covered Total %
statement 48 48 100.0
branch 16 16 100.0
condition 2 3 66.6
subroutine 14 14 100.0
pod 0 1 0.0
total 80 82 97.5


line stmt bran cond sub pod time code
1             # $Id$
2             # $Source$
3             # $Author$
4             # $HeadURL$
5             # $Revision$
6             # $Date$
7             package Class::Dot::Object;
8              
9 14     14   84 use strict;
  14         26  
  14         496  
10 14     14   82 use warnings;
  14         32  
  14         424  
11 14     14   75 use version;
  14         27  
  14         82  
12 14     14   1251 use 5.00600;
  14         48  
  14         635  
13 14     14   7588 use dot::meta; # the metaclass psuedoclass.
  14         36  
  14         748  
14              
15             our $VERSION = qv('2.0.0_15');
16             our $AUTHORITY = 'cpan:ASKSH';
17              
18              
19 14     14   82 use Class::Dot::Registry;
  14         28  
  14         7136  
20             my $REGISTRY = Class::Dot::Registry->new();
21              
22             my $ATTR_EXISTS = 1;
23             my $ATTR_EXISTS_CACHED = 2;
24             my $ATTR_NO_SUCH_ATTR; #<< must be undef.
25              
26             sub __getattr__ {
27 91     91   4335 my ($self, $attribute) = @_;
28 91 100       250 if (! exists $self->{$attribute}) {
29 10         38 my $attr_meta = $self->__meta__($attribute);
30 10 100       39 return if not defined $attr_meta;
31 9         45 $self->{$attribute} = $attr_meta->default_value();
32             }
33 90         549 return $self->{$attribute};
34             }
35              
36             sub __hasattr__ {
37 67     67   2988 my ($self, $attribute) = @_;
38              
39 67         504 my $is_finalized = $REGISTRY->is_finalized($self);
40 67         176 my $isa_cache = $REGISTRY->get_isa_cache_for($self);
41 67 100 66     190 if ($is_finalized && $isa_cache) {
42 3 100       21 return defined $isa_cache->{$attribute} ? $ATTR_EXISTS_CACHED
43             : $ATTR_NO_SUCH_ATTR;
44             }
45              
46 64         181 my $property_meta = $self->__metaclass__->property;
47 64 100       204 return $property_meta->traverse_isa_for_property($self, $attribute)
48             ? $ATTR_EXISTS
49             : $ATTR_NO_SUCH_ATTR;
50             }
51              
52             sub __setattr__ {
53 53     53   96 my ($self, $attribute, $value) = @_;
54 53 100       144 return if not $self->__hasattr__($attribute);
55              
56 34         111 $self->{$attribute} = $value;
57              
58 34         91 return 1;
59             }
60              
61             sub __is_finalized__ {
62 5     5   10 my ($self) = @_;
63              
64 5         18 return $REGISTRY->is_finalized($self);
65             }
66              
67             sub __finalize__ {
68 2     2   5 my ($self) = @_;
69 2 100       6 return 1 if $self->__is_finalized__;
70            
71 1         4 my $metaclass = $self->__metaclass__;
72 1         5 my $isa_cache = $metaclass->property->traverse_isa_for_property($self);
73              
74 1         7 return $REGISTRY->finalize_class($self, $isa_cache);
75             }
76              
77             sub __meta__ {
78 40     40   8120 my ($self, $property_name) = @_;
79            
80 40         157 my $all_meta = $self->__metaclass__->property->properties_for_class($self);
81              
82 40 100       283 return defined $property_name ? $all_meta->{$property_name}
83             : $all_meta
84             }
85              
86             sub __metaclass__ {
87 109     109   310 goto &HOW;
88             }
89              
90             sub HOW {
91 114     114 0 1389 my ($self) = @_;
92 114         409 return $REGISTRY->get_metaclass_for($self);
93             }
94              
95             1;
96              
97             __END__