File Coverage

blib/lib/Data/Annotated.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package Data::Annotated;
2 2     2   54161 use Data::Path;
  0            
  0            
3              
4             use warnings;
5             use strict;
6              
7             =head1 NAME
8              
9             Data::Annotated - Data structure Annotation module
10              
11             =head1 VERSION
12              
13             Version 0.01
14              
15             =cut
16              
17             our $VERSION = '0.2';
18              
19             my $callbacks = {
20             key_does_not_exist => sub {},
21             index_does_not_exist => sub {},
22             retrieve_index_from_non_array => sub {},
23             retrieve_key_from_non_hash => sub {},
24             };
25              
26             =head1 SYNOPSIS
27              
28             use Data::Annotated;
29              
30             my $da = Data::Annotated->new();
31            
32             $da->annotate('/foo/bar[2]/baz', {desc => 'this is an interesting field'});
33             $da->annotate('/some/other/path', {test => 1, runthis => sub { print 'I was one'; } });
34            
35             my $struct = {some => {other => {path => 1}}};
36             my @annotations = $da->cat_annotation();
37            
38             # this will print out "I was one';
39             $annotations[0]{runthis}->() if $struct->{some}{other}{path} == $annotations[0]{test};
40              
41             =head1 METHODS
42              
43             =head2 new()
44              
45             instantiate a new Data::Annotated object;
46              
47             =cut
48              
49             sub new {
50             return bless {}, shift;
51             }
52              
53             =head2 annotate($path, \%annotation);
54              
55             Annotate a piece of a data structure. The path is an XPath like path like L
56             uses. The annotation can be any scalar value. Possible uses are String for descriptive
57             text. Or a reference to a more complex data structure.
58              
59             =cut
60              
61             sub annotate {
62             my ($self, $path, $anno) = @_;
63             croak('Not a valid path: '.$path) unless $self->_validate_path($path);
64             $self->{$path} = $anno;
65             }
66              
67             =head2 cat_annotation($data)
68              
69             spit out the annotations for a data structure. Returns the annotations that apply
70             for the passed in data structures. Does not return an annotation if the data doesn't
71             contain the data location it is matched to.
72              
73             =cut
74              
75             sub cat_annotation {
76             my ($self, $data) = @_;
77             my $dp = Data::Path->new($data, $callbacks);
78             my @paths = grep { $dp->get($_) } keys(%$self);
79             return map { $self->get_annotation($_) } @paths;
80             }
81              
82             =head2 get_annotation($path);
83              
84             retrieves an annotation keyed by the path in the data structure.
85              
86             =cut
87              
88             sub get_annotation {
89             my ($self, $path) = @_;
90             return {path => $_, %{$self->{$path}}} if $self->_validate_path($path);
91             carp('Invalid Path requested: '. $path);
92             }
93              
94             =head1 INTERNAL METHODS
95              
96             =head2 _validate_path($path)
97              
98             validates a L path for validity.
99              
100             =cut
101              
102             sub _validate_path {
103             my ($self, $path) = @_;
104             return 1 if $path =~ qr/^\/.*[^\/]$/;
105             return;
106             }
107              
108              
109              
110             =head1 TODO
111              
112             Should Data::Annotate wrap data? or stay a collection of annotations?
113            
114             Make Data::Annotate return the data from a requested path.
115             my $info = $da->get($path, $data) basically just a wrapper around L get()
116              
117             =head1 COPYRIGHT & LICENSE
118              
119             Copyright 2007 Jeremy Wall, all rights reserved.
120              
121             This program is free software; you can redistribute it and/or modify it
122             under the same terms as Perl itself.
123              
124             =head1 AUTHOR
125              
126             Jeremy Wall, C<< >>
127              
128             =cut
129              
130             1;