File Coverage

blib/lib/Tie/HashObject.pm
Criterion Covered Total %
statement 3 90 3.3
branch 0 40 0.0
condition 0 6 0.0
subroutine 1 15 6.6
pod 0 1 0.0
total 4 152 2.6


line stmt bran cond sub pod time code
1             package Tie::HashObject;
2              
3             sub new {
4 0     0 0   my $class = shift;
5 0           my %args = @_;
6              
7 0           my %tied;
8             #tie %tied, Tie::HashMethods, {keys=> $args{keys}};
9 0           tie %tied, Tie::HashMethods;
10              
11 0           my $self = bless \%tied, $class;
12 0 0         $tied{keys} = $args{keys} if exists $args{keys};
13 0           $tied{object} = $self;
14 0           return $self;
15             }
16             1;
17              
18             package Tie::HashMethods;
19              
20 1     1   2383 use strict;
  1         2  
  1         2743  
21              
22             our $VERSION = '0.01';
23              
24             sub defined_public_keys {
25 0     0     my $self = shift;
26 0           my $keys = [];
27 0           foreach my $key (@{$self->method_keys}) {
  0            
28 0 0         push @$keys, $key if defined $self->{storage}->{$key};
29             }
30 0           return $keys;
31             }
32              
33              
34             sub DESTROY {
35 0     0     my $self = shift;
36             # Note: I don't know if this is neccessary.
37             # but it gets rid of the self reference...
38 0           $self->{object} = {};
39             # I worried about having a reference inside a reference... but I'm not sure whether this is a problem.
40             }
41              
42             sub object {
43 0     0     my $self = shift;
44 0 0         $self->{object} = shift if defined $_[0];
45 0           return $self->{object};
46             }
47              
48             sub method_keys {
49 0     0     my $self = shift;
50 0 0         $self->{keys} = shift if defined $_[0];
51 0           return $self->{keys};
52             }
53              
54             sub TIEHASH {
55 0     0     my $class = shift;
56 0           my $args = shift;
57              
58 0           my $self = bless {}, $class;
59              
60 0 0         if (exists $args->{keys}) {
61 0           $self->method_keys($args->{keys});
62             }
63              
64 0           return $self;
65             }
66              
67             sub STORE {
68 0     0     my $self = shift;
69 0           my $key = shift;
70 0           my $value = shift;
71              
72 0 0 0       if (!defined $self->object && $key eq 'object') {
    0 0        
    0          
    0          
73 0 0         if (ref $value) {
74 0           $self->object($value);
75             } else {
76 0           warn sprintf('First call to %s->{object} must be a reference to an object', __PACKAGE__);
77             }
78             }
79             elsif (!defined $self->method_keys && $key eq 'keys') {
80 0           $self->method_keys($value);
81             }
82 0           elsif ( $self->object->isa( (caller)[0] ) ) {
83 0           return $self->{storage}->{$key} = $value;
84             }
85             elsif (grep /^$key$/, @{$self->method_keys}) {
86 0           $self->object->$key($value);
87             }
88             else {
89 0           warn "Invalid key: " . $key;
90             }
91             }
92              
93             sub FETCH {
94 0     0     my $self = shift;
95 0           my $key = shift;
96 0 0         if ( $self->object->isa((caller)[0]) ) {
  0 0          
97 0           return $self->{storage}->{$key};
98             }
99             elsif (grep /^$key$/, @{$self->method_keys}) {
100 0           return $self->object->$key;
101             }
102             else {
103 0           warn "Invalid key: " . $key;
104             }
105             }
106              
107             sub FIRSTKEY {
108 0     0     my $self = shift;
109 0 0         if ( $self->object->isa((caller)[0]) ) {
110 0           return (keys %{$self->{storage}})[0];
  0            
111             }
112             else {
113             # we have to do this for data dumps...
114 0           return (@{$self->defined_public_keys})[0];
  0            
115             }
116             }
117              
118             sub NEXTKEY {
119 0     0     my $self = shift;
120 0           my $last_method = shift;
121              
122 0           my @keys;
123              
124 0 0         if ( $self->object->isa((caller)[0]) ) {
125 0           @keys = keys %{$self->{storage}};
  0            
126             }
127             else {
128 0           @keys = @{$self->defined_public_keys};
  0            
129             }
130 0           my $next_index = 0;
131 0           foreach my $key (@keys) {
132 0           $next_index++;
133 0 0         last if $last_method eq $key;
134             }
135 0 0         return $next_index > scalar @keys ? undef : $keys[$next_index];
136             }
137              
138              
139             sub EXISTS {
140 0     0     my $self = shift;
141 0           my $key = shift;
142              
143 0 0         if ( $self->object->isa((caller)[0]) ) {
144 0           return exists $self->{storage}->{$key};
145             }
146             else {
147 0           return (grep /^$key$/, @{$self->defined_public_keys});
  0            
148             }
149             }
150              
151             sub DELETE {
152 0     0     my $self = shift;
153 0           my $key = shift;
154              
155 0 0         if ( $self->object->isa((caller)[0]) ) {
156 0           return delete $self->{storage}->{$key};
157             }
158             else {
159 0           warn "Cannot delete methods. Please set the values instead.";
160             }
161             }
162              
163             # override this method if you have some default for clearing the method hash values...
164             sub CLEAR {
165 0     0     my $self = shift;
166 0 0         if ( $self->object->isa((caller)[0]) ) {
167 0           $self->{storage} = {};
168             }
169             else {
170 0           warn "Cannot clear tied method calls";
171             }
172             }
173              
174             sub SCALAR {
175 0     0     my $self = shift;
176 0 0         if ( $self->object->isa((caller)[0]) ) {
177 0           return scalar keys %{$self->{storage}};
  0            
178             }
179             else {
180 0           return scalar @{$self->defined_public_keys};
  0            
181             }
182             }
183              
184             1;
185              
186             __END__