File Coverage

blib/lib/Rope/Object.pm
Criterion Covered Total %
statement 47 60 78.3
branch 14 24 58.3
condition 3 12 25.0
subroutine 9 13 69.2
pod 0 2 0.0
total 73 111 65.7


line stmt bran cond sub pod time code
1             package Rope::Object;
2              
3 5     5   36 use strict;
  5         9  
  5         143  
4 5     5   25 use warnings;
  5         8  
  5         4455  
5              
6             sub TIEHASH {
7 6     6   19 my ($class, $obj) = @_;
8 6   50     22 my $self = bless $obj || {}, $class;
9             $self->set_value(
10             $_,
11             $self->{properties}->{$_}->{value},
12             $self->{properties}->{$_}
13 6         10 ) for keys %{$self->{properties}};
  6         44  
14 6         20 $self->compile();
15 6         21 return $self;
16             }
17              
18             sub compile {
19 6     6 0 23 my ($self) = @_;
20 6         10 $self->{keys} = scalar keys %{$self->{properties}};
  6         29  
21             $self->{sort_keys} = [sort {
22             $self->{properties}->{$a}->{index} <=> $self->{properties}->{$b}->{index}
23 6         24 } grep { $self->{properties}->{$_}->{enumerable} } keys %{$self->{properties}}];
  13         40  
  23         52  
  6         21  
24 6         12 return $self;
25             }
26              
27             sub set_value {
28 31     31 0 67 my ($self, $key, $value, $spec) = @_;
29 31 100       65 if (defined $value) {
30 29 100       94 if ($spec->{type}) {
31 12         56 $value = eval {
32 12         29 $spec->{type}->($value);
33             };
34 12 100 66     7350 if ($@ || ! defined $value) {
35 1         13 my @caller = caller(1);
36 1 50       6 if ($caller[0] eq 'Rope::Object') {
37 0         0 die sprintf("Failed to instantiate object (%s) property (%s) failed type validation. %s", $self->{name}, $key, $@);
38             }
39 1         9 die sprintf("Cannot set property (%s) in object (%s) failed type validation on line %s file %s: %s", $key, $self->{name}, $caller[2], $caller[1], $@);
40             }
41             }
42 28         55 $spec->{value} = $value;
43             }
44 30         73 return $spec->{value};
45             }
46            
47             sub STORE {
48 10     10   29 my ($self, $key, $value) = @_;
49 10         22 my $k = $self->{properties}->{$key};
50 10 100       23 if ($k) {
    50          
51 9 100       24 if ($k->{writeable}) {
    50          
52 8         21 $self->set_value($key, $value, $k);
53             } elsif ($k->{configurable}) {
54 0 0 0     0 if ((ref($value) || "") eq (ref($k->{value}) || "")) {
      0        
55 0         0 $self->set_value($key, $value, $k);
56             } else {
57 0         0 die "Cannot change Object ($self->{name}) property ($key) type";
58             }
59             } else {
60 1         11 die "Cannot set Object ($self->{name}) property ($key) it is only readable";
61             }
62             } elsif (! $self->{locked}) {
63             $self->{properties}->{$key} = {
64             value => $value,
65             writable => 1,
66             configurable => 1,
67             enumerable => 1,
68             index => ++$self->{keys}
69 1         5 };
70 1         2 push @{$self->{sort_keys}}, $key;
  1         4  
71             } else {
72 0         0 die "Object ($self->{name}) is locked you cannot extend with new properties";
73             }
74 8         24 return $self;
75             }
76            
77             sub FETCH {
78 27     27   357 my ($self, $key) = @_;
79 27         55 my $k = $self->{properties}->{$key};
80 27 50       133 return $k ? $k->{value} : undef;
81             }
82            
83             sub FIRSTKEY {
84 2     2   9 goto &NEXTKEY;
85             }
86            
87             sub NEXTKEY {
88 7     7   11 return (each @{$_[0]->{sort_keys}})[1];
  7         29  
89             }
90            
91             sub EXISTS {
92 0     0     exists $_[0]->{properties}->{$_[1]};
93             }
94            
95             sub DELETE {
96 0     0     my $k = $_[0]->{properties}->{$_[1]};
97 0 0 0       my $del = !$_[0]->{locked} && $k->{writeable} ? delete $_[0]->{properties}->{$_[1]} : undef;
98 0 0         $_[0]->compile() if $del;
99 0           return $del;
100             }
101            
102             sub CLEAR {
103 0     0     return;
104             #%{$_[0]->{properties}} = ()
105             }
106            
107             sub SCALAR {
108 0     0     scalar keys %{$_[0]->{properties}}
  0            
109             }
110              
111             1;
112              
113             __END__