File Coverage

blib/lib/Tie/Subset/Array.pm
Criterion Covered Total %
statement 65 68 100.0
branch 14 16 100.0
condition 6 6 100.0
subroutine 18 19 100.0
pod n/a
total 103 109 100.0


line stmt bran cond sub pod time code
1             #!perl
2             package Tie::Subset::Array;
3 2     2   110678 use warnings;
  2         12  
  2         68  
4 2     2   11 use strict;
  2         4  
  2         37  
5 2     2   10 use warnings::register;
  2         4  
  2         196  
6 2     2   13 use Carp;
  2         4  
  2         1882  
7              
8             # For AUTHOR, COPYRIGHT, AND LICENSE see the bottom of this file
9              
10             =head1 Name
11              
12             Tie::Subset::Array - Tie an array to a subset of another array
13              
14             =head1 Synopsis
15              
16             use Tie::Subset::Array;
17             my @array = (55,66,77,88,99);
18             tie my @subset, 'Tie::Subset::Array', \@array, [1,2,3];
19             print "$subset[1]\n"; # prints "77"
20             $subset[2]++; # modifies $array[3]
21              
22             =head1 Description
23              
24             This class for tied arrays provides a "view" of a subset of an array.
25              
26             =over
27              
28             =cut
29              
30             our $VERSION = '0.02';
31              
32             =item Cing
33              
34             tie my @subset, 'Tie::Subset::Array', \@array, \@indices;
35              
36             You must specify which subset of indices from the original array
37             should be part of the new array. (Indices that do not yet exist in
38             the original array may be specified.) The subset (tied array) will
39             be the same size as C<@indices>, and is indexed by the usual 0 to
40             C<$#subset>.
41              
42             =cut
43              
44             sub TIEARRAY { ## no critic (RequireArgUnpacking)
45 8 100   8   3874 @_==3 or croak "bad number of arguments to tie";
46 7         18 my ($class, $arr, $idx) = @_;
47 7 100       113 ref $arr eq 'ARRAY' or croak "must provide arrayref to tie";
48 6 100       100 ref $idx eq 'ARRAY' or croak "must provide index list to tie";
49 5 100 100     13 for (@$idx) { croak "bad array index '$_'" if ref || !/\A[0-9]+\z/ }
  22         284  
50 3         12 my $self = { arr => $arr, idx => [@$idx] };
51 3         13 return bless $self, $class;
52             }
53              
54             sub FETCHSIZE {
55 54     54   4813 my ($self) = @_;
56 54         66 return scalar @{ $self->{idx} };
  54         142  
57             }
58              
59             =item Fetching
60              
61             If the index is within the bounds of the tied array, the value from
62             the underlying array is returned, otherwise returns nothing (undef).
63              
64             =cut
65              
66             sub FETCH {
67 54     54   297 my ($self,$i) = @_;
68             # uncoverable branch true
69 54 50       117 return if $i < 0;
70 54 100       87 return if $i > $#{ $self->{idx} };
  54         119  
71 50         139 return $self->{arr}[ $self->{idx}[$i] ];
72             }
73              
74             =item Storing
75              
76             If the index is within the bounds of the tied array, the new value
77             will be stored in the underlying array, otherwise the operation is
78             ignored and a warning issued.
79              
80             =cut
81              
82             sub STORE {
83 7     7   1568 my ($self,$i,$v) = @_;
84 7 50       19 return if $i < 0; # uncoverable branch true
85 7 100       12 if ( $i > $#{ $self->{idx} } ) {
  7         20  
86 2         343 warnings::warnif("storing values outside of the subset not (yet) supported in ".ref($self));
87 2         114 return;
88             }
89 5         23 return $self->{arr}[ $self->{idx}[$i] ] = $v;
90             }
91              
92             =item C
93              
94             B The Perl documentation strongly discourages from calling
95             L on array values.
96              
97             Will return true only if the index C in the subset I
98             the corresponding index in the underlying array C.
99              
100             =cut
101              
102             sub EXISTS {
103 3     3   8 my ($self,$i) = @_;
104 3   100     27 return exists $self->{idx}[$i] && exists $self->{arr}[ $self->{idx}[$i] ];
105             }
106              
107             sub UNTIE {
108 1     1   352 my ($self) = @_;
109 1         2 $self->{arr} = undef;
110 1         3 $self->{idx} = undef;
111 1         5 return;
112             }
113              
114             =item I
115              
116             Any operations that modify the size of the tied array are not (yet)
117             supported (because it is ambiguous how such operations should
118             affect the underlying array). Attempting to change the tied array's
119             size, including using C, C, C, C,
120             C, assigning to the C<$#array> notation, clearing the
121             array, etc. will currently do nothing and cause a warning to be
122             issued, and operations that normally return a value will return
123             nothing.
124              
125             The above is also true for attempting to C array elements,
126             which the Perl documentation strongly discourages anyway.
127              
128             A future version of this module may lift these limitations (if a
129             useful default behavior exists).
130              
131             =cut
132              
133             sub STORESIZE {
134 1     1   370 my ($self,$s) = @_;
135 1         117 warnings::warnif("extending or shrinking of ".ref($self)." not (yet) supported");
136 1         45 return;
137             }
138              
139             sub CLEAR {
140 1     1   338 my ($self) = @_;
141 1         115 warnings::warnif("clearing of ".ref($self)." not (yet) supported");
142 1         35 return;
143             }
144              
145             sub PUSH {
146 1     1   346 my ($self,@list) = @_;
147 1         111 warnings::warnif("pushing onto ".ref($self)." not (yet) supported");
148 1         42 return;
149             }
150              
151             sub POP {
152 1     1   340 my ($self) = @_;
153 1         107 warnings::warnif("popping from ".ref($self)." not (yet) supported");
154 1         34 return;
155             }
156              
157             sub SHIFT {
158 1     1   349 my ($self) = @_;
159 1         105 warnings::warnif("shifting from ".ref($self)." not (yet) supported");
160 1         34 return;
161             }
162              
163             sub UNSHIFT {
164 1     1   341 my ($self,@list) = @_;
165 1         105 warnings::warnif("unshifting onto ".ref($self)." not (yet) supported");
166 1         41 return;
167             }
168              
169             sub SPLICE {
170 1     1   340 my ($self,$off,$len,@list) = @_;
171 1         106 warnings::warnif("splicing ".ref($self)." not (yet) supported");
172 1         50 return;
173             }
174              
175             sub EXTEND {
176             # uncoverable subroutine
177 0     0   0 my ($self,$s) = @_; # uncoverable statement
178 0         0 warnings::warnif("extending ".ref($self)." not (yet) supported"); # uncoverable statement
179 0         0 return; # uncoverable statement
180             }
181              
182             sub DELETE {
183 1     1   333 my ($self,$i) = @_;
184 1         105 warnings::warnif("deleting from ".ref($self)." not (yet) supported");
185 1         64 return;
186             }
187              
188             1;
189             __END__