File Coverage

blib/lib/Tie/Subset/Array.pm
Criterion Covered Total %
statement 33 66 50.0
branch 8 12 66.6
condition 5 12 41.6
subroutine 8 19 42.1
pod n/a
total 54 109 49.5


line stmt bran cond sub pod time code
1             #!perl
2             package Tie::Subset::Array;
3 2     2   99789 use warnings;
  2         17  
  2         71  
4 2     2   11 use strict;
  2         4  
  2         39  
5 2     2   10 use warnings::register;
  2         3  
  2         238  
6 2     2   14 use Carp;
  2         4  
  2         1828  
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.01';
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 hash 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 3 50   3   1032 @_==3 or croak "bad number of arguments to tie";
46 3         11 my ($class, $arr, $idx) = @_;
47 3 50       12 ref $arr eq 'ARRAY' or croak "must provide arrayref to tie";
48 3 50       10 ref $idx eq 'ARRAY' or croak "must provide index list to tie";
49 3 50 33     8 for (@$idx) { croak "bad array index '$_'" if ref || !/\A[0-9]+\z/ }
  20         122  
50 3         17 my $self = { arr => $arr, idx => [@$idx] };
51 3         13 return bless $self, $class;
52             }
53              
54             sub FETCHSIZE {
55 51     51   4703 my ($self) = @_;
56 51         66 return scalar @{ $self->{idx} };
  51         122  
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   340 my ($self,$i) = @_;
68 54 100 66     123 return if $i < 0 || $i > $#{ $self->{idx} };
  54         164  
69 50         148 return $self->{arr}[ $self->{idx}[$i] ];
70             }
71              
72             =item Storing
73              
74             If the index is within the bounds of the tied array, the new value
75             will be stored in the underlying array, otherwise the operation is
76             ignored and a warning issued.
77              
78             =cut
79              
80             sub STORE {
81 7     7   1262 my ($self,$i,$v) = @_;
82 7 100 66     24 if ( $i < 0 || $i > $#{ $self->{idx} } ) {
  7         29  
83 2         368 warnings::warnif("storing values outside of the subset not (yet) supported in ".ref($self));
84 2         113 return;
85             }
86 5         23 return $self->{arr}[ $self->{idx}[$i] ] = $v;
87             }
88              
89             =item C
90              
91             B The Perl documentation strongly discourages from calling
92             L on array values.
93              
94             Will return true only if the index C in the subset I
95             the corresponding index in the underlying array C.
96              
97             =cut
98              
99             sub EXISTS {
100 0     0     my ($self,$i) = @_;
101 0   0       return exists $self->{idx}[$i] && exists $self->{arr}[ $self->{idx}[$i] ];
102             }
103              
104             sub UNTIE {
105 0     0     my ($self) = @_;
106 0           $self->{arr} = undef;
107 0           $self->{idx} = undef;
108 0           return;
109             }
110              
111             =item I
112              
113             Any operations that modify the size of the tied array are not (yet)
114             supported (because it is ambiguous how such operations should
115             affect the underlying array). Attempting to change the tied array's
116             size, including using C, C, C, C,
117             C, assigning to the C<$#array> notation, clearing the
118             array, etc. will currently do nothing and cause a warning to be
119             issued, and operations that normally return a value will return
120             nothing.
121              
122             The above is also true for attempting to C array elements,
123             which the Perl documentation strongly discourages anyway.
124              
125             A future version of this module may lift these limitations (if a
126             useful default behavior exists).
127              
128             =cut
129              
130             sub STORESIZE {
131 0     0     my ($self,$s) = @_;
132 0           warnings::warnif("extending or shrinking of ".ref($self)." not (yet) supported");
133 0           return;
134             }
135              
136             sub CLEAR {
137 0     0     my ($self) = @_;
138 0           warnings::warnif("clearing of ".ref($self)." not (yet) supported");
139 0           return;
140             }
141              
142             sub PUSH {
143 0     0     my ($self,@list) = @_;
144 0           warnings::warnif("pushing onto ".ref($self)." not (yet) supported");
145 0           return;
146             }
147              
148             sub POP {
149 0     0     my ($self) = @_;
150 0           warnings::warnif("popping from ".ref($self)." not (yet) supported");
151 0           return;
152             }
153              
154             sub SHIFT {
155 0     0     my ($self) = @_;
156 0           warnings::warnif("shifting from ".ref($self)." not (yet) supported");
157 0           return;
158             }
159              
160             sub UNSHIFT {
161 0     0     my ($self,@list) = @_;
162 0           warnings::warnif("unshifting onto ".ref($self)." not (yet) supported");
163 0           return;
164             }
165              
166             sub SPLICE {
167 0     0     my ($self,$off,$len,@list) = @_;
168 0           warnings::warnif("splicing ".ref($self)." not (yet) supported");
169 0           return;
170             }
171              
172             sub EXTEND {
173 0     0     my ($self,$s) = @_;
174 0           warnings::warnif("extending ".ref($self)." not (yet) supported");
175 0           return;
176             }
177              
178             sub DELETE {
179 0     0     my ($self,$i) = @_;
180 0           warnings::warnif("deleting from ".ref($self)." not (yet) supported");
181 0           return;
182             }
183              
184             1;
185             __END__