File Coverage

blib/lib/List/Compare/Base/_Auxiliary.pm
Criterion Covered Total %
statement 451 452 99.7
branch 135 136 99.2
condition 89 89 100.0
subroutine 39 39 100.0
pod n/a
total 714 716 99.7


line stmt bran cond sub pod time code
1             package List::Compare::Base::_Auxiliary;
2             $VERSION = 0.53;
3 52     52   230 use Carp;
  52         76  
  52         7334  
4             @ISA = qw(Exporter);
5             @EXPORT_OK = qw|
6             _validate_2_seenhashes
7             _validate_seen_hash
8             _validate_multiple_seenhashes
9             _calculate_array_seen_only
10             _calculate_seen_only
11             _calculate_intermediate
12             _calculate_union_only
13             _calculate_union_seen_only
14             _calculate_sharedref
15             _subset_subengine
16             _chart_engine_regular
17             _chart_engine_multiple
18             _equivalent_subengine
19             _index_message1
20             _index_message2
21             _index_message3
22             _index_message4
23             _prepare_listrefs
24             _subset_engine_multaccel
25             _calc_seen
26             _calc_seen1
27             _equiv_engine
28             _argument_checker_0
29             _argument_checker
30             _argument_checker_1
31             _argument_checker_2
32             _argument_checker_3
33             _argument_checker_3a
34             _argument_checker_4
35             _alt_construct_tester
36             _alt_construct_tester_1
37             _alt_construct_tester_2
38             _alt_construct_tester_3
39             _alt_construct_tester_4
40             _alt_construct_tester_5
41             |;
42             %EXPORT_TAGS = (
43             calculate => [ qw(
44             _calculate_array_seen_only
45             _calculate_seen_only
46             _calculate_intermediate
47             _calculate_union_only
48             _calculate_union_seen_only
49             _calculate_sharedref
50             ) ],
51             checker => [ qw(
52             _argument_checker_0
53             _argument_checker
54             _argument_checker_1
55             _argument_checker_2
56             _argument_checker_3
57             _argument_checker_3a
58             _argument_checker_4
59             ) ],
60             tester => [ qw(
61             _alt_construct_tester
62             _alt_construct_tester_1
63             _alt_construct_tester_2
64             _alt_construct_tester_3
65             _alt_construct_tester_4
66             _alt_construct_tester_5
67             ) ],
68             );
69 52     52   268 use strict;
  52         78  
  52         246556  
70             local $^W =1;
71              
72             my $bad_lists_msg = q{If argument is single hash ref, you must have a 'lists' key whose value is an array ref};
73              
74             sub _validate_2_seenhashes {
75 27     27   28 my ($refL, $refR) = @_;
76 27         32 my (%seenL, %seenR);
77 0         0 my (%badentriesL, %badentriesR);
78 27         104 foreach (keys %$refL) {
79 144 100 100     102 if (${$refL}{$_} =~ /^\d+$/ and ${$refL}{$_} > 0) {
  144         513  
  143         340  
80 142         95 $seenL{$_} = ${$refL}{$_};
  142         289  
81             } else {
82 2         3 $badentriesL{$_} = ${$refL}{$_};
  2         6  
83             }
84             }
85 27         101 foreach (keys %$refR) {
86 133 100 100     187 if (${$refR}{$_} =~ /^\d+$/ and ${$refR}{$_} > 0) {
  133         392  
  132         293  
87 131         98 $seenR{$_} = ${$refR}{$_};
  131         272  
88             } else {
89 2         3 $badentriesR{$_} = ${$refR}{$_};
  2         5  
90             }
91             }
92 27         42 my $msg = q{};
93 27 100 100     136 if ( (keys %badentriesL) or (keys %badentriesR) ) {
94 4         5 $msg .= "\nValues in a 'seen-hash' may only be positive integers.\n";
95 4         29 $msg .= " These elements have invalid values:\n";
96 4 100       6 if (keys %badentriesL) {
97 2         3 $msg .= " First hash in arguments:\n";
98             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
99 2         9 foreach (sort keys %badentriesL);
100             }
101 4 100       9 if (keys %badentriesR) {
102 2         2 $msg .= " Second hash in arguments:\n";
103             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
104 2         9 foreach (sort keys %badentriesR);
105             }
106 4         8 $msg .= "Correct invalid values before proceeding";
107 4         424 croak "$msg: $!";
108             }
109 23         92 return (\%seenL, \%seenR);
110             }
111              
112             sub _validate_seen_hash {
113 441 100   441   837 if (@_ > 2) {
114 206         587 _validate_multiple_seenhashes( [@_] );
115             } else {
116 235         333 my ($l, $r) = @_;
117 235         204 my (%badentriesL, %badentriesR);
118 235         693 foreach (keys %$l) {
119 20         42 $badentriesL{$_} = ${$l}{$_}
  1450         4325  
120 1450 100 100     1044 unless (${$l}{$_} =~ /^\d+$/ and ${$l}{$_} > 0);
  1431         4151  
121             }
122 235         661 foreach (keys %$r) {
123 20         43 $badentriesR{$_} = ${$r}{$_}
  1423         3617  
124 1423 100 100     985 unless (${$r}{$_} =~ /^\d+$/ and ${$r}{$_} > 0);
  1404         4054  
125             }
126 235         350 my $msg = q{};
127 235 100 100     1193 if ( (keys %badentriesL) or (keys %badentriesR) ) {
128 22         29 $msg .= "\nValues in a 'seen-hash' must be numeric.\n";
129 22         22 $msg .= " These elements have invalid values:\n";
130 22 100       39 if (keys %badentriesL) {
131 20         20 $msg .= " First hash in arguments:\n";
132             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
133 20         73 foreach (sort keys %badentriesL);
134             }
135 22 100       43 if (keys %badentriesR) {
136 20         19 $msg .= " Second hash in arguments:\n";
137             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
138 20         62 foreach (sort keys %badentriesR);
139             }
140 22         24 $msg .= "Correct invalid values before proceeding";
141 22         2604 croak "$msg: $!";
142             }
143             }
144             }
145              
146             sub _validate_multiple_seenhashes {
147 206     206   194 my $hashrefsref = shift;
148 206         193 my (%badentries);
149 206         277 for (my $i = 0; $i <= $#{$hashrefsref}; $i++) {
  1246         2075  
150 1040         782 foreach my $k (keys %{$hashrefsref->[$i]}) {
  1040         1971  
151 5588 100 100     23482 unless ($hashrefsref->[$i]->{$k} =~ /^\d+$/ and $hashrefsref->[$i]->{$k} > 0) {
152 2         6 $badentries{$i}{$k} = $hashrefsref->[$i]->{$k};
153             }
154             }
155             }
156 206         240 my $msg = q{};
157 206 100       616 if (scalar(keys %badentries)) {
158 2         3 $msg .= "\nValues in a 'seen-hash' must be positive integers.\n";
159 2         2 $msg .= " These elements have invalid values:\n\n";
160 2         4 foreach my $b (sort keys %badentries) {
161 2         3 $msg .= " Hash $b:\n";
162 2         3 foreach my $val (sort keys %{$badentries{$b}}) {
  2         5  
163 2         11 $msg .= " Bad key-value pair: $val\t$badentries{$b}->{$val}\n";
164             }
165             }
166 2         3 $msg .= "Correct invalid values before proceeding";
167 2         186 croak "$msg: $!";
168             }
169             }
170              
171             sub _list_builder {
172 6052     6052   5299 my ($aref, $x) = @_;
173 6052 100       4444 if (ref(${$aref}[$x]) eq 'HASH') {
  6052         9862  
174 4072         2923 return keys %{${$aref}[$x]};
  4072         2775  
  4072         9014  
175             } else {
176 1980         1403 return @{${$aref}[$x]};
  1980         1381  
  1980         4317  
177             }
178             }
179              
180             sub _calculate_array_seen_only {
181 136     136   159 my $aref = shift;
182 136         138 my (@seen);
183 136         172 for (my $i = 0; $i <= $#{$aref}; $i++) {
  744         1338  
184 608         693 my %seenthis = ();
185 608         767 foreach my $el ( _list_builder($aref, $i) ) {
186 3564         3830 $seenthis{$el}++;
187             }
188 608         1280 push @seen, \%seenthis;
189             }
190 136         285 return \@seen;
191             }
192              
193             sub _calculate_seen_only {
194 901     901   849 my $aref = shift;
195 901         789 my (%seen);
196 901         942 for (my $i = 0; $i <= $#{$aref}; $i++) {
  4687         8145  
197 3786         3680 my %seenthis = ();
198 3786         4522 foreach my $h ( _list_builder($aref, $i) ) {
199 21918         23228 $seenthis{$h}++;
200             }
201 3786         7642 $seen{$i} = \%seenthis;
202             }
203 901         2091 return \%seen;
204             }
205              
206             sub _calculate_intermediate {
207 32     32   41 my $aref = shift;
208 32         60 my $aseenref = _calculate_array_seen_only($aref);
209 32         42 my @vals = sort { scalar(keys(%{$a})) <=> scalar(keys(%{$b})) } @{$aseenref};
  192         130  
  192         199  
  192         253  
  32         75  
210 32         35 my %intermediate = map { $_ => 1 } keys %{$vals[0]};
  128         183  
  32         86  
211 32         93 for my $l ( 1..$#vals ) {
212 384         593 %intermediate = map { $_ => 1 }
  736         747  
213 128         208 grep { exists $intermediate{$_} }
214 128         101 keys %{$vals[$l]};
215             }
216 32         165 return \%intermediate;
217             }
218              
219             sub _calculate_union_only {
220 225     225   252 my $aref = shift;
221 225         230 my (%union);
222 225         318 for (my $i = 0; $i <= $#{$aref}; $i++) {
  1155         2098  
223 930         1228 foreach my $h ( _list_builder($aref, $i) ) {
224 5470         6439 $union{$h}++;
225             }
226             }
227 225         574 return \%union;
228             }
229              
230             sub _calculate_union_seen_only {
231 160     160   183 my $aref = shift;
232 160         145 my (%union, %seen);
233 160         219 for (my $i = 0; $i <= $#{$aref}; $i++) {
  888         1650  
234 728         743 my %seenthis = ();
235 728         914 foreach my $h ( _list_builder($aref, $i) ) {
236 4276         3865 $seenthis{$h}++;
237 4276         4293 $union{$h}++;
238             }
239 728         1594 $seen{$i} = \%seenthis;
240             }
241 160         432 return (\%union, \%seen);
242             }
243              
244             sub _calculate_sharedref {
245 176     176   211 my $seenrefsref = shift;
246              
247 176         241 my %intermediate = ();
248 176         171 for my $href (@{$seenrefsref}) {
  176         253  
249 736         611 my %this = map { $_ => 1 } keys(%{$href});
  4128         4847  
  736         1428  
250 736         1449 for my $k (keys %this) {;
251 4128         4830 $intermediate{$k}++;
252             };
253             }
254              
255 176         230 my $sharedref;
256 176         375 for my $k (keys %intermediate) {
257 1664 100       3006 $sharedref->{$k}++ if $intermediate{$k} > 1;
258             }
259 176         568 return $sharedref;
260             }
261              
262             sub _is_list_subset {
263 1364     1364   1237 my ( $subset, $superset ) = @_;
264             # return false if the superset value is false
265             # for any subset value.
266             # note that this does *not* validate overlap of
267             # the keys; it validates the truth of supserset
268             # values.
269 1364   100     6215 $superset->{ $_ } or return 0 for keys %$subset;
270 440         810 return 1;
271             }
272              
273             sub _subset_subengine {
274 204     204   205 my $aref = shift;
275 204         197 my (@xsubset);
276 204         167 my %seen = %{_calculate_seen_only($aref)};
  204         308  
277 204         573 foreach my $i (keys %seen) {
278 796         1094 foreach my $j (keys %seen) {
279 3524 100       6368 if ( $i eq $j ) {
    100          
280 796         1510 $xsubset[$i][$j] = 1;
281             }
282             elsif ( $i gt $j ) {
283 1364 100       1031 if ( scalar(keys %{ $seen{$i} }) == scalar(keys %{ $seen{$j} }) ){
  1364 100       1529  
  1364 50       1987  
  1064         994  
284 300         469 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
285 300         591 $xsubset[$j][$i] = $xsubset[$i][$j];
286             }
287 1064         1452 elsif ( scalar(keys %{ $seen{$i} }) < scalar(keys %{ $seen{$j} }) ){
  12         13  
288 1052         1311 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
289 1052         1739 $xsubset[$j][$i] = 0;
290             }
291 12         23 elsif ( scalar(keys %{ $seen{$i} }) > scalar(keys %{ $seen{$j} }) ){
292 12         16 $xsubset[$j][$i] = _is_list_subset($seen{$j}, $seen{$i});
293 12         22 $xsubset[$i][$j] = 0;
294             }
295             }
296             }
297             }
298 204         879 return \@xsubset;
299             }
300             sub _chart_engine_regular {
301 32     32   50 my $aref = shift;
302 32         62 my @sub_or_eqv = @$aref;
303 32         56 my $title = shift;
304 32         39 my ($v, $w, $t);
305 32         1209 print "\n";
306 32         209 print $title, ' Relationships', "\n\n";
307 32         170 print ' Right: 0 1', "\n\n";
308 32         272 print 'Left: 0: 1 ', $sub_or_eqv[0], "\n\n";
309 32         446 print ' 1: ', $sub_or_eqv[1], ' 1', "\n\n";
310             }
311              
312             sub _chart_engine_multiple {
313 48     48   72 my $aref = shift;
314 48         259 my @sub_or_eqv = @$aref;
315 48         70 my $title = shift;
316 48         65 my ($v, $w, $t);
317 48         1833 print "\n";
318 48         317 print $title, ' Relationships', "\n\n";
319 48         230 print ' Right:';
320 48         251 for ($v = 0; $v <= $#sub_or_eqv; $v++) {
321 216         1555 print ' ', $v;
322             }
323 48         242 print "\n\n";
324 48         220 print 'Left: 0:';
325 48         264 my @firstrow = @{$sub_or_eqv[0]};
  48         131  
326 48         154 for ($t = 0; $t <= $#firstrow; $t++) {
327 216         1557 print ' ', $firstrow[$t];
328             }
329 48         250 print "\n\n";
330 48         272 for ($w = 1; $w <= $#sub_or_eqv; $w++) {
331 168         228 my $length_left = length($w);
332 168         175 my $x = '';
333 168         1157 print ' ' x (8 - $length_left), $w, ':';
334 168         294 my @row = @{$sub_or_eqv[$w]};
  168         328  
335 168         389 for ($x = 0; $x <= $#row; $x++) {
336 816         5270 print ' ', $row[$x];
337             }
338 168         1062 print "\n\n";
339             }
340 48         433 1; # force return true value
341             }
342              
343             sub _equivalent_subengine {
344 76     76   95 my $aref = shift;
345 76         82 my @xsubset = @{_subset_subengine($aref)};
  76         122  
346 76         109 my (@xequivalent);
347 76         208 for (my $f = 0; $f <= $#xsubset; $f++) {
348 296         467 for (my $g = 0; $g <= $#xsubset; $g++) {
349 1312         1245 $xequivalent[$f][$g] = 0;
350 1312 100 100     4015 $xequivalent[$f][$g] = 1
351             if ($xsubset[$f][$g] and $xsubset[$g][$f]);
352             }
353             }
354 76         237 return \@xequivalent;
355             }
356              
357             sub _index_message1 {
358 170     170   212 my ($index, $dataref) = @_;
359 170         743 my $method = (caller(1))[3];
360 162         1091 croak "Argument to method $method must be the array index of the target list \n in list of arrays passed as arguments to the constructor: $!"
361             unless (
362             $index =~ /^\d+$/
363 170 100 100     2468 and $index <= ${$dataref}{'maxindex'}
364             );
365             }
366              
367             sub _index_message2 {
368 135     135   157 my $dataref = shift;
369 135         156 my ($index_left, $index_right);
370 135         544 my $method = (caller(1))[3];
371 135 100 100     2410 croak "Method $method requires 2 arguments: $!"
372             unless (@_ == 0 || @_ == 2);
373 123 100       241 if (@_ == 0) {
374 18         30 $index_left = 0;
375 18         35 $index_right = 1;
376             } else {
377 105         173 ($index_left, $index_right) = @_;
378 105         309 foreach ($index_left, $index_right) {
379 196         1550 croak "Each argument to method $method must be a valid array index for the target list \n in list of arrays passed as arguments to the constructor: $!"
380             unless (
381             $_ =~ /^\d+$/
382 199 100 100     1350 and $_ <= ${$dataref}{'maxindex'}
383             );
384             }
385             }
386 112         310 return ($index_left, $index_right);
387             }
388              
389             sub _index_message3 {
390 170     170   302 my ($index, $maxindex) = @_;
391 170         686 my $method = (caller(1))[3];
392 170 100 100     3213 croak "Argument to method $method must be the array index of the target list \n in list of arrays passed as arguments to the constructor: $!"
393             unless (
394             $index =~ /^\d+$/
395             and $index <= $maxindex
396             );
397             }
398              
399             sub _index_message4 {
400 126     126   191 my $maxindex = shift;
401 126         106 my ($index_left, $index_right);
402 126         479 my $method = (caller(1))[3];
403 126 100 100     2381 croak "Method $method requires 2 arguments: $!"
404             unless (@_ == 0 || @_ == 2);
405 114 100       214 if (@_ == 0) {
406 16         31 $index_left = 0;
407 16         21 $index_right = 1;
408             } else {
409 98         132 ($index_left, $index_right) = @_;
410 98         142 foreach ($index_left, $index_right) {
411 186 100 100     2227 croak "Each argument to method $method must be a valid array index for the target list \n in list of arrays passed as arguments to the constructor: $!"
412             unless (
413             $_ =~ /^\d+$/
414             and $_ <= $maxindex
415             );
416             }
417             }
418 104         235 return ($index_left, $index_right);
419             }
420              
421             sub _prepare_listrefs {
422 752     752   815 my $dataref = shift;
423 752         628 delete ${$dataref}{'unsort'};
  752         1379  
424 752         710 my (@listrefs);
425 752         707 foreach my $lref (sort {$a <=> $b} keys %{$dataref}) {
  5761         6300  
  752         2569  
426 3788         2719 push(@listrefs, ${$dataref}{$lref});
  3788         5570  
427             };
428 752         2006 return \@listrefs;
429             }
430              
431             sub _subset_engine_multaccel {
432 64     64   151 my $dataref = shift;
433 64         187 my $aref = _prepare_listrefs($dataref);
434 64         73 my ($index_left, $index_right) = _index_message4($#{$aref}, @_);
  64         182  
435              
436 56         119 my $xsubsetref = _subset_subengine($aref);
437 56         53 return ${$xsubsetref}[$index_left][$index_right];
  56         216  
438             }
439              
440             sub _calc_seen {
441 718     718   759 my ($refL, $refR) = @_;
442             # We've already guaranteed that args are both array refs or both hash
443             # refs. So checking the left-hand one is sufficient.
444 718 100       1417 if (ref($refL) eq 'ARRAY') {
445 365         314 my (%seenL, %seenR);
446 365         609 foreach (@$refL) { $seenL{$_}++ }
  2717         3588  
447 365         588 foreach (@$refR) { $seenR{$_}++ }
  2683         3141  
448 365         1123 return (\%seenL, \%seenR);
449             } else {
450 353         718 return ($refL, $refR);
451             }
452             }
453              
454             sub _equiv_engine {
455 56     56   72 my ($hrefL, $hrefR) = @_;
456 56         62 my (%intersection, %Lonly, %Ronly, %LorRonly);
457 56         56 my $LequivalentR_status = 0;
458              
459 56         62 foreach (keys %{$hrefL}) {
  56         167  
460 312 100       221 exists ${$hrefR}{$_} ? $intersection{$_}++ : $Lonly{$_}++;
  312         656  
461             }
462              
463 56         90 foreach (keys %{$hrefR}) {
  56         115  
464 296 100       511 $Ronly{$_}++ unless (exists $intersection{$_});
465             }
466              
467 56         164 $LorRonly{$_}++ foreach ( (keys %Lonly), (keys %Ronly) );
468 56 100       131 $LequivalentR_status = 1 if ( (keys %LorRonly) == 0);
469 56         264 return $LequivalentR_status;
470             }
471              
472             sub _argument_checker_0 {
473 889     889   1340 my @args = @_;
474 889         1039 my $first_ref = ref($args[0]);
475 889         1807 my @temp = @args[1..$#args];
476 889         830 my ($testing);
477 889         811 my $condition = 1;
478 889         1735 while (defined ($testing = shift(@temp)) ) {
479 2083 100       4871 unless (ref($testing) eq $first_ref) {
480 18         20 $condition = 0;
481 18         43 last;
482             }
483             }
484 889 100       3458 croak "Arguments must be either all array references or all hash references: $!"
485             unless $condition;
486 871 100       1828 _validate_seen_hash(@args) if $first_ref eq 'HASH';
487 849         2175 return (@args);
488             }
489              
490             sub _argument_checker {
491 842     842   832 my $argref = shift;
492 842 100       5568 croak "'$argref' must be an array ref" unless ref($argref) eq 'ARRAY';
493 806         698 my @args = _argument_checker_0(@{$argref});
  806         1330  
494 770         2341 return (@args);
495             }
496              
497             sub _argument_checker_1 {
498 267     267   232 my $argref = shift;
499 267         342 my @args = @{$argref};
  267         348  
500 267 100       712 croak "Subroutine call requires 2 references as arguments: $!"
501             unless @args == 2;
502 264         407 return (_argument_checker($args[0]), ${$args[1]}[0]);
  264         706  
503             }
504              
505             sub _argument_checker_2 {
506 18     18   28 my $argref = shift;
507 18         41 my @args = @$argref;
508 18 100       267 croak "Subroutine call requires 2 references as arguments: $!"
509             unless @args == 2;
510 16         38 return (_argument_checker($args[0]), $args[1]);
511             }
512              
513             # _argument_checker_3 is currently set-up to handle either 1 or 2 arguments
514             # in get_unique and get_complement
515             # The first argument is an arrayref holding refs to lists ('unsorted' has been
516             # stripped off).
517             # The second argument is an arrayref holding a single item (index number of
518             # item being tested)
519             # Note: Currently we're only checking for the quantity of arguments -- not
520             # their types. This should be fixed.
521             sub _argument_checker_3 {
522 115     115   147 my $argref = shift;
523 115         117 my @args = @{$argref};
  115         187  
524 115 100       255 if (@args == 1) {
    100          
525 65         149 return (_argument_checker($args[0]), 0);
526             } elsif (@args == 2) {
527 40         88 return (_argument_checker($args[0]), ${$args[1]}[0]);
  32         155  
528             } else {
529 10         1449 croak "Subroutine call requires 1 or 2 references as arguments: $!";
530             }
531             }
532              
533             sub _argument_checker_3a {
534 34     34   85 my $argref = shift;
535 34         62 my @args = @{$argref};
  34         65  
536 34 100       93 if (@args == 1) {
537 32         86 return [ _argument_checker($args[0]) ];
538             } else {
539 2         249 croak "Subroutine call requires exactly 1 reference as argument: $!";
540             }
541             }
542              
543             sub _argument_checker_4 {
544 136     136   149 my $argref = shift;
545 136         117 my @args = @{$argref};
  136         236  
546 136 100       271 if (@args == 1) {
    100          
547 84         156 return (_argument_checker($args[0]), [0,1]);
548             } elsif (@args == 2) {
549 49 100       51 if (@{$args[1]} == 2) {
  49         99  
550 44         41 my $last_index = $#{$args[0]};
  44         113  
551 44         49 foreach my $i (@{$args[1]}) {
  44         78  
552 80 100 100     1408 croak "No element in index position $i in list of list references passed as first argument to function: $!"
553             unless ($i =~ /^\d+$/ and $i <= $last_index);
554             }
555 36         78 return (_argument_checker($args[0]), $args[1]);
556             } else {
557 5         616 croak "Must provide index positions corresponding to two lists: $!";
558             }
559             } else {
560 3         326 croak "Subroutine call requires 1 or 2 references as arguments: $!";
561             }
562             }
563              
564             sub _calc_seen1 {
565 706     706   926 my @listrefs = @_;
566             # _calc_seen1() is applied after _argument_checker(), which checks to make
567             # sure that the references in its output are either all arrayrefs
568             # or all seenhashrefs
569             # hence, _calc_seen1 only needs to determine whether it's dealing with
570             # arrayrefs or seenhashrefs, then, if arrayrefs, calculate seenhashes
571 706 100       1201 if (ref($listrefs[0]) eq 'ARRAY') {
572 368         285 my (@seenrefs);
573 368         448 foreach my $aref (@listrefs) {
574 1250         885 my (%seenthis);
575 1250         1057 foreach my $j (@{$aref}) {
  1250         1303  
576 8088         8484 $seenthis{$j}++;
577             }
578 1250         1819 push(@seenrefs, \%seenthis);
579             }
580 368         846 return \@seenrefs;
581             } else {
582 338         788 return \@listrefs;
583             }
584             }
585              
586             # _alt_construct_tester prepares for _argument_checker in
587             # get_union get_intersection get_symmetric_difference get_shared get_nonintersection
588             sub _alt_construct_tester {
589 317     317   614 my @args = @_;
590 317         308 my ($argref, $unsorted);
591 317 100 100     1440 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
592 144         170 my $hashref = shift;
593 144         1837 croak "$bad_lists_msg: $!"
594 130         1728 unless ( ${$hashref}{'lists'}
595 144 100 100     274 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
596 116         108 $argref = ${$hashref}{'lists'};
  116         127  
597 116 100       101 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  116         233  
598             } else {
599 173 100 100     667 $unsorted = shift(@args)
600             if ($args[0] eq '-u' or $args[0] eq '--unsorted');
601 173         378 $argref = shift(@args);
602             }
603 289         691 return ($argref, $unsorted);
604             }
605              
606             # _alt_construct_tester_1 prepares for _argument_checker_1 in
607             # is_member_which is_member_which_ref is_member_any
608             sub _alt_construct_tester_1 {
609 276     276   351 my @args = @_;
610 276         207 my ($argref);
611 276 100 100     785 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
612 119         96 my (@returns);
613 119         99 my $hashref = $args[0];
614 119         530 croak "$bad_lists_msg: $!"
615 116         591 unless ( ${$hashref}{'lists'}
616 119 100 100     93 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
617 113         503 croak "If argument is single hash ref, you must have an 'item' key: $!"
618 113 100       95 unless ${$hashref}{'item'};
619 110         93 @returns = ( ${$hashref}{'lists'}, [${$hashref}{'item'}] );
  110         109  
  110         219  
620 110         165 $argref = \@returns;
621             } else {
622 157         162 $argref = \@args;
623             }
624 267         467 return $argref;
625             }
626              
627             # _alt_construct_tester_2 prepares for _argument_checker_2 in
628             # are_members_which are_members_any
629             sub _alt_construct_tester_2 {
630 26     26   55 my @args = @_;
631 26 100 100     189 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
632 16         22 my $hashref = $args[0];
633 16         245 croak "$bad_lists_msg: $!"
634 14         240 unless ( ${$hashref}{'lists'}
635 16 100 100     18 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
636 12         235 croak "If argument is single hash ref, you must have an 'items' key whose value is an array ref: $!"
637 10         242 unless ( ${$hashref}{'items'}
638 12 100 100     16 and (ref(${$hashref}{'items'}) eq 'ARRAY') );
639 8         14 return [ (${$hashref}{'lists'}, ${$hashref}{'items'}) ];
  8         15  
  8         29  
640             } else {
641 10         27 return \@args;
642             }
643             }
644              
645             # _alt_construct_tester_3 prepares for _argument_checker_3 in
646             # get_unique get_complement
647             sub _alt_construct_tester_3 {
648 157     157   344 my @args = @_;
649 157         153 my ($argref, $unsorted);
650 157 100 100     877 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
651 68         65 my (@returns);
652 68         68 my $hashref = $args[0];
653 68         691 croak "$bad_lists_msg: $!"
654 64         732 unless ( ${$hashref}{'lists'}
655 68 100 100     60 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
656 60         120 @returns = defined ${$hashref}{'item'}
  16         18  
657 16         29 ? (${$hashref}{'lists'}, [${$hashref}{'item'}])
  44         75  
658 60 100       64 : (${$hashref}{'lists'});
659 60         70 $argref = \@returns;
660 60 100       52 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  60         188  
661             } else {
662 89 100 100     392 $unsorted = shift(@args) if ($args[0] eq '-u' or $args[0] eq '--unsorted');
663 89         144 $argref = \@args;
664             }
665 149         373 return ($argref, $unsorted);
666             }
667              
668             # _alt_construct_tester_4 prepares for _argument_checker_4 in
669             # is_LsubsetR is_RsubsetL is_LequivalentR is_LdisjointR
670             sub _alt_construct_tester_4 {
671 146     146   298 my @args = @_;
672 146         137 my ($argref);
673 146 100 100     673 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
674 70         63 my (@returns);
675 70         248 my $hashref = $args[0];
676 70         848 croak "$bad_lists_msg: $!"
677 65         883 unless ( ${$hashref}{'lists'}
678 70 100 100     62 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
679 60         105 @returns = defined ${$hashref}{'pair'}
  18         18  
680 18         30 ? (${$hashref}{'lists'}, ${$hashref}{'pair'})
  42         68  
681 60 100       73 : (${$hashref}{'lists'});
682 60         96 $argref = \@returns;
683             } else {
684 76         91 $argref = \@args;
685             }
686 136         267 return $argref;
687             }
688              
689             # _alt_construct_tester_5 prepares for _argument_checker in
690             # print_subset_chart print_equivalence_chart
691             sub _alt_construct_tester_5 {
692 22     22   48 my @args = @_;
693 22         24 my ($argref);
694 22 100       53 if (@args == 1) {
695 20 100       54 if (ref($args[0]) eq 'HASH') {
696 12         15 my $hashref = shift;
697 12         222 croak "Need to define 'lists' key properly: $!"
698 10         478 unless ( ${$hashref}{'lists'}
699 12 100 100     18 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
700 8         10 $argref = ${$hashref}{'lists'};
  8         15  
701             } else {
702 8         12 $argref = shift(@args);
703             }
704             } else {
705 2         224 croak "Subroutine call requires exactly 1 reference as argument: $!";
706             }
707 16         42 return $argref;
708             }
709              
710             1;
711              
712             __END__