File Coverage

blib/lib/BusyBird/SafeData.pm
Criterion Covered Total %
statement 28 28 100.0
branch 2 2 100.0
condition n/a
subroutine 10 10 100.0
pod 5 5 100.0
total 45 45 100.0


line stmt bran cond sub pod time code
1             package BusyBird::SafeData;
2 18     18   17716 use v5.8.0;
  18         44  
  18         689  
3 18     18   79 use strict;
  18         24  
  18         496  
4 18     18   82 use warnings;
  18         84  
  18         576  
5 18     18   73 use Exporter 5.57 qw(import);
  18         245  
  18         553  
6 18     18   9890 use Data::Diver ();
  18         15252  
  18         3776  
7              
8             our @EXPORT_OK = qw(safed);
9              
10             sub new {
11 1609     1609 1 2791 my ($class, $data) = @_;
12 1609         6794 return bless \$data, $class;
13             }
14              
15             sub safed {
16 1609     1609 1 9273 return __PACKAGE__->new(@_);
17             }
18              
19             sub original {
20 95     95 1 8543 return ${shift()};
  95         366  
21             }
22              
23             sub val {
24 3503     3503 1 64676 my ($self, @path) = @_;
25 3503         6153 return scalar(Data::Diver::Dive($$self, map { "$_" } @path));
  5539         14650  
26             }
27              
28             sub array {
29 81     81 1 6494 my ($self, @path) = @_;
30 81         172 my $val = $self->val(@path);
31 81 100       2529 if(ref($val) eq 'ARRAY') {
32 6         22 return @$val;
33             }else {
34 75         276 return ();
35             }
36             }
37              
38             1;
39              
40             =pod
41              
42             =head1 NAME
43              
44             BusyBird::SafeData - a wrapper of a complex data structure to access its internals safely
45              
46             =head1 SYNOPSIS
47              
48             use BusyBird::SafeData qw(safed);
49            
50             my $data = {
51             foo => {
52             bar => [
53             0, 1, 2
54             ],
55             buzz => { hoge => 100 }
56             }
57             };
58            
59             my $sd = safed($data);
60            
61             $sd->original; ## => $data
62            
63             $sd->val("foo", "bar", 1); ## => 1
64             $sd->val("foo", "buzz", "FOO"); ## => undef
65             $sd->val("foo", "quux", "hoge"); ## => undef (and no autovivification)
66             $sd->val("foo", "bar", "FOO"); ## => undef (and no exception thrown)
67             $sd->val("foo", "buzz", "hoge", "FOO"); ## => undef (and no exception thrown)
68            
69             $sd->array("foo", "bar"); ## => (0, 1, 2)
70             $sd->array("foo", "buzz"); ## => ()
71             $sd->array("foo", "bar", 1); ## => ()
72              
73             =head1 DESCRIPTION
74              
75             L is a wrapper around a complex data structure to provide a safe way to access its internal data.
76              
77             =head1 EXPORTABLE FUNCTIONS
78              
79             The following function is exported only by request.
80              
81             =head2 $sd = safed($data)
82              
83             Same as C<< BusyBird::SafeData->new($data). >>
84              
85             =head1 CLASS METHODS
86              
87             =head2 $sd = BusyBird::SafeData->new($data)
88              
89             The constructor.
90              
91             C<$data> is any scalar. C<$sd> wraps the given C<$data>.
92              
93             =head1 OBJECT METHODS
94              
95             =head2 $data = $sd->original()
96              
97             Returns the original C<$data> that C<$sd> wraps.
98              
99             =head2 $val = $sd->val(@path)
100              
101             Return the value specified by C<@path> from C<$sd>.
102              
103             C<@path> is a list of indices/keys from the root of the C<$sd> down to the value you want.
104             If it cannot traverse C<@path> completely, it returns C.
105              
106             This method never autovivifies anything in C<$sd>.
107              
108             =head2 @vals = $sd->array(@path)
109              
110             Return the list of values in the array-ref specified by C<@path>.
111             If it cannot traverse C<@path> completely, it returns an empty list.
112             If the value at the C<@path> is not an array-ref, it returns an empty list.
113              
114             =head1 AUTHOR
115              
116             Toshio Ito C<< >>
117              
118             =cut