File Coverage

blib/lib/EO/Hierarchy.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package EO::Hierarchy;
2              
3 1     1   32576 use strict;
  1         3  
  1         35  
4 1     1   6 use warnings;
  1         2  
  1         28  
5              
6 1     1   933 use EO::Hash;
  0            
  0            
7             use EO::delegate;
8             use base qw( EO );
9              
10             our $VERSION = 0.96;
11              
12             EO::Hierarchy->mk_accessors( qw( parent ) );
13              
14             exception EO::Hierarchy::Error::NoParent;
15             exception EO::Hierarchy::Error::InvalidState;
16              
17             sub init {
18             my $self = shift;
19             if ($self->SUPER::init( @_ )) {
20             $self->delegate( EO::Hash->new );
21             return 1;
22             }
23             return 0;
24             }
25              
26             sub add_child {
27             my $self = shift;
28             my $name = shift;
29             ## we want to share the delegated class, which makes this look
30             ## sort of ugly, but not bad enough to make me want a 'class' method.
31             ## on everything.
32             my $child = ref($self)->new
33             ->delegate( ref($self->delegate)->new )
34             ->parent( $self );
35             $self->at($name, $child);
36             }
37              
38              
39             ## this took me a while to work out, so I'd better document it.
40             sub at {
41             my $self = shift;
42             my $key = shift;
43              
44             throw EO::Error::InvalidParameters text => 'no key specified' unless defined( $key );
45              
46             if (@_) {
47             ## if its a set, then we do just that, no
48             ## need to worry about it.
49             return $self->delegate->at( $key, @_ );
50             }
51              
52             ## right, its a get, here is the fun.
53             if ( !defined( $self->delegate->at( $key ) ) && $self->parent ) {
54             ## if we don't have a defined value at the key, but
55             ## we do have a parent then we ask the parent.
56             return $self->parent->at( $key );
57             } elsif (!defined( $self->delegate->at($key) ) && !$self->parent) {
58             ## if we don't have a defined value at the key, and
59             ## we have no parent, then we throw an Exception.
60             throw EO::Hierarchy::Error::NoParent
61             text => 'have gone as far as we can';
62             } elsif (defined( $self->delegate->at( $key ) )) {
63             ## if we have a key, then we return it
64             return $self->delegate->at( $key );
65             } else {
66             ## we should absolutely never get here. I don't know
67             ## how we would get here, but it all seems hairy enough
68             ## to warrant an exception.
69             throw EO::Hierarchy::Error::InvalidState
70             text => 'how the heck did we get here?'
71             }
72             }
73              
74             1;
75              
76             __END__