File Coverage

blib/lib/List/Compare/Base/_Auxiliary.pm
Criterion Covered Total %
statement 449 449 100.0
branch 134 134 100.0
condition 89 89 100.0
subroutine 39 39 100.0
pod n/a
total 711 711 100.0


line stmt bran cond sub pod time code
1             package List::Compare::Base::_Auxiliary;
2             our $VERSION = 0.55;
3 52     52   374 use Carp;
  52         105  
  52         9199  
4             our @ISA = qw(Exporter);
5             our @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             our %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   390 use strict;
  52         163  
  52         274685  
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   64 my ($refL, $refR) = @_;
76 27         48 my (%seenL, %seenR, %badentriesL, %badentriesR);
77 27         112 foreach (keys %$refL) {
78 144 100 100     195 if (${$refL}{$_} =~ /^\d+$/ and ${$refL}{$_} > 0) {
  144         570  
  143         416  
79 142         189 $seenL{$_} = ${$refL}{$_};
  142         320  
80             } else {
81 2         5 $badentriesL{$_} = ${$refL}{$_};
  2         5  
82             }
83             }
84 27         100 foreach (keys %$refR) {
85 133 100 100     175 if (${$refR}{$_} =~ /^\d+$/ and ${$refR}{$_} > 0) {
  133         452  
  132         335  
86 131         171 $seenR{$_} = ${$refR}{$_};
  131         299  
87             } else {
88 2         4 $badentriesR{$_} = ${$refR}{$_};
  2         7  
89             }
90             }
91 27         76 my $msg = q{};
92 27 100 100     148 if ( (keys %badentriesL) or (keys %badentriesR) ) {
93 4         10 $msg .= "\nValues in a 'seen-hash' may only be positive integers.\n";
94 4         10 $msg .= " These elements have invalid values:\n";
95 4 100       20 if (keys %badentriesL) {
96 2         14 $msg .= " First hash in arguments:\n";
97             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
98 2         14 foreach (sort keys %badentriesL);
99             }
100 4 100       15 if (keys %badentriesR) {
101 2         5 $msg .= " Second hash in arguments:\n";
102             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
103 2         12 foreach (sort keys %badentriesR);
104             }
105 4         8 $msg .= "Correct invalid values before proceeding";
106 4         532 croak "$msg: $!";
107             }
108 23         108 return (\%seenL, \%seenR);
109             }
110              
111             sub _validate_seen_hash {
112 441 100   441   976 if (@_ > 2) {
113 206         537 _validate_multiple_seenhashes( [@_] );
114             } else {
115 235         431 my ($l, $r) = @_;
116 235         367 my (%badentriesL, %badentriesR);
117 235         706 foreach (keys %$l) {
118 20         53 $badentriesL{$_} = ${$l}{$_}
119 1450 100 100     1950 unless (${$l}{$_} =~ /^\d+$/ and ${$l}{$_} > 0);
  1450         4778  
  1431         4080  
120             }
121 235         788 foreach (keys %$r) {
122 20         44 $badentriesR{$_} = ${$r}{$_}
123 1423 100 100     1866 unless (${$r}{$_} =~ /^\d+$/ and ${$r}{$_} > 0);
  1423         3959  
  1404         3860  
124             }
125 235         465 my $msg = q{};
126 235 100 100     1310 if ( (keys %badentriesL) or (keys %badentriesR) ) {
127 22         44 $msg .= "\nValues in a 'seen-hash' must be numeric.\n";
128 22         34 $msg .= " These elements have invalid values:\n";
129 22 100       46 if (keys %badentriesL) {
130 20         34 $msg .= " First hash in arguments:\n";
131             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
132 20         81 foreach (sort keys %badentriesL);
133             }
134 22 100       51 if (keys %badentriesR) {
135 20         34 $msg .= " Second hash in arguments:\n";
136             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
137 20         61 foreach (sort keys %badentriesR);
138             }
139 22         75 $msg .= "Correct invalid values before proceeding";
140 22         2372 croak "$msg: $!";
141             }
142             }
143             }
144              
145             sub _validate_multiple_seenhashes {
146 206     206   305 my $hashrefsref = shift;
147 206         314 my (%badentries);
148 206         361 for (my $i = 0; $i <= $#{$hashrefsref}; $i++) {
  1246         2532  
149 1040         1351 foreach my $k (keys %{$hashrefsref->[$i]}) {
  1040         2614  
150 5588 100 100     21479 unless ($hashrefsref->[$i]->{$k} =~ /^\d+$/ and $hashrefsref->[$i]->{$k} > 0) {
151 2         8 $badentries{$i}{$k} = $hashrefsref->[$i]->{$k};
152             }
153             }
154             }
155 206         385 my $msg = q{};
156 206 100       664 if (scalar(keys %badentries)) {
157 2         5 $msg .= "\nValues in a 'seen-hash' must be positive integers.\n";
158 2         5 $msg .= " These elements have invalid values:\n\n";
159 2         7 foreach my $b (sort keys %badentries) {
160 2         6 $msg .= " Hash $b:\n";
161 2         5 foreach my $val (sort keys %{$badentries{$b}}) {
  2         6  
162 2         10 $msg .= " Bad key-value pair: $val\t$badentries{$b}->{$val}\n";
163             }
164             }
165 2         5 $msg .= "Correct invalid values before proceeding";
166 2         242 croak "$msg: $!";
167             }
168             }
169              
170             sub _list_builder {
171 6052     6052   9690 my ($aref, $x) = @_;
172 6052 100       7898 if (ref(${$aref}[$x]) eq 'HASH') {
  6052         12139  
173 4072         5180 return keys %{${$aref}[$x]};
  4072         4993  
  4072         12504  
174             } else {
175 1980         2654 return @{${$aref}[$x]};
  1980         2536  
  1980         5743  
176             }
177             }
178              
179             sub _calculate_array_seen_only {
180 136     136   237 my $aref = shift;
181 136         223 my (@seen);
182 136         230 for (my $i = 0; $i <= $#{$aref}; $i++) {
  744         1487  
183 608         865 my %seenthis = ();
184 608         986 foreach my $el ( _list_builder($aref, $i) ) {
185 3564         5519 $seenthis{$el}++;
186             }
187 608         1365 push @seen, \%seenthis;
188             }
189 136         410 return \@seen;
190             }
191              
192             sub _calculate_seen_only {
193 901     901   1453 my $aref = shift;
194 901         1346 my (%seen);
195 901         1430 for (my $i = 0; $i <= $#{$aref}; $i++) {
  4687         9636  
196 3786         5368 my %seenthis = ();
197 3786         6125 foreach my $h ( _list_builder($aref, $i) ) {
198 21918         33747 $seenthis{$h}++;
199             }
200 3786         8614 $seen{$i} = \%seenthis;
201             }
202 901         2602 return \%seen;
203             }
204              
205             sub _calculate_intermediate {
206 32     32   72 my $aref = shift;
207 32         74 my $aseenref = _calculate_array_seen_only($aref);
208 32         72 my @vals = sort { scalar(keys(%{$a})) <=> scalar(keys(%{$b})) } @{$aseenref};
  192         317  
  192         278  
  192         324  
  32         87  
209 32         91 my %intermediate = map { $_ => 1 } keys %{$vals[0]};
  128         278  
  32         105  
210 32         120 for my $l ( 1..$#vals ) {
211 384         752 %intermediate = map { $_ => 1 }
212 736         1208 grep { exists $intermediate{$_} }
213 128         205 keys %{$vals[$l]};
  128         274  
214             }
215 32         173 return \%intermediate;
216             }
217              
218             sub _calculate_union_only {
219 225     225   421 my $aref = shift;
220 225         371 my (%union);
221 225         420 for (my $i = 0; $i <= $#{$aref}; $i++) {
  1155         2388  
222 930         1680 foreach my $h ( _list_builder($aref, $i) ) {
223 5470         8844 $union{$h}++;
224             }
225             }
226 225         601 return \%union;
227             }
228              
229             sub _calculate_union_seen_only {
230 160     160   280 my $aref = shift;
231 160         281 my (%union, %seen);
232 160         305 for (my $i = 0; $i <= $#{$aref}; $i++) {
  888         2359  
233 728         1041 my %seenthis = ();
234 728         1225 foreach my $h ( _list_builder($aref, $i) ) {
235 4276         6253 $seenthis{$h}++;
236 4276         6368 $union{$h}++;
237             }
238 728         1765 $seen{$i} = \%seenthis;
239             }
240 160         652 return (\%union, \%seen);
241             }
242              
243             sub _calculate_sharedref {
244 176     176   363 my $seenrefsref = shift;
245              
246 176         329 my %intermediate = ();
247 176         265 for my $href (@{$seenrefsref}) {
  176         351  
248 736         966 my %this = map { $_ => 1 } keys(%{$href});
  4128         6955  
  736         1798  
249 736         1925 for my $k (keys %this) {;
250 4128         6572 $intermediate{$k}++;
251             };
252             }
253              
254 176         305 my $sharedref;
255 176         491 for my $k (keys %intermediate) {
256 1664 100       3609 $sharedref->{$k}++ if $intermediate{$k} > 1;
257             }
258 176         639 return $sharedref;
259             }
260              
261             sub _is_list_subset {
262 1364     1364   2130 my ( $subset, $superset ) = @_;
263             # return false if the superset value is false
264             # for any subset value.
265             # note that this does *not* validate overlap of
266             # the keys; it validates the truth of supserset
267             # values.
268 1364   100     6023 $superset->{ $_ } or return 0 for keys %$subset;
269 440         1008 return 1;
270             }
271              
272             sub _subset_subengine {
273 204     204   357 my $aref = shift;
274 204         351 my (@xsubset);
275 204         295 my %seen = %{_calculate_seen_only($aref)};
  204         442  
276 204         760 foreach my $i (keys %seen) {
277 796         1535 foreach my $j (keys %seen) {
278 3524 100       7227 if ( $i eq $j ) {
    100          
279 796         1696 $xsubset[$i][$j] = 1;
280             }
281             elsif ( $i gt $j ) {
282 1364 100       1803 if ( scalar(keys %{ $seen{$i} }) == scalar(keys %{ $seen{$j} }) ){
  1364 100       2243  
  1364         2438  
283 300         628 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
284 300         763 $xsubset[$j][$i] = $xsubset[$i][$j];
285             }
286 1064         1571 elsif ( scalar(keys %{ $seen{$i} }) < scalar(keys %{ $seen{$j} }) ){
  1064         1798  
287 1052         1854 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
288 1052         2414 $xsubset[$j][$i] = 0;
289             }
290             else {
291 12         27 $xsubset[$j][$i] = _is_list_subset($seen{$j}, $seen{$i});
292 12         28 $xsubset[$i][$j] = 0;
293             }
294             }
295             }
296             }
297 204         968 return \@xsubset;
298             }
299             sub _chart_engine_regular {
300 32     32   72 my $aref = shift;
301 32         77 my @sub_or_eqv = @$aref;
302 32         62 my $title = shift;
303 32         79 my ($v, $w, $t);
304 32         1228 print "\n";
305 32         426 print $title, ' Relationships', "\n\n";
306 32         339 print ' Right: 0 1', "\n\n";
307 32         538 print 'Left: 0: 1 ', $sub_or_eqv[0], "\n\n";
308 32         651 print ' 1: ', $sub_or_eqv[1], ' 1', "\n\n";
309             }
310              
311             sub _chart_engine_multiple {
312 48     48   111 my $aref = shift;
313 48         137 my @sub_or_eqv = @$aref;
314 48         97 my $title = shift;
315 48         106 my ($v, $w, $t);
316 48         3084 print "\n";
317 48         693 print $title, ' Relationships', "\n\n";
318 48         529 print ' Right:';
319 48         309 for ($v = 0; $v <= $#sub_or_eqv; $v++) {
320 216         2917 print ' ', $v;
321             }
322 48         547 print "\n\n";
323 48         508 print 'Left: 0:';
324 48         210 my @firstrow = @{$sub_or_eqv[0]};
  48         222  
325 48         256 for ($t = 0; $t <= $#firstrow; $t++) {
326 216         2856 print ' ', $firstrow[$t];
327             }
328 48         515 print "\n\n";
329 48         360 for ($w = 1; $w <= $#sub_or_eqv; $w++) {
330 168         466 my $length_left = length($w);
331 168         271 my $x = '';
332 168         1724 print ' ' x (8 - $length_left), $w, ':';
333 168         446 my @row = @{$sub_or_eqv[$w]};
  168         496  
334 168         539 for ($x = 0; $x <= $#row; $x++) {
335 816         10099 print ' ', $row[$x];
336             }
337 168         1981 print "\n\n";
338             }
339 48         537 1; # force return true value
340             }
341              
342             sub _equivalent_subengine {
343 76     76   150 my $aref = shift;
344 76         117 my @xsubset = @{_subset_subengine($aref)};
  76         166  
345 76         154 my (@xequivalent);
346 76         236 for (my $f = 0; $f <= $#xsubset; $f++) {
347 296         593 for (my $g = 0; $g <= $#xsubset; $g++) {
348 1312         1955 $xequivalent[$f][$g] = 0;
349 1312 100 100     3666 $xequivalent[$f][$g] = 1
350             if ($xsubset[$f][$g] and $xsubset[$g][$f]);
351             }
352             }
353 76         291 return \@xequivalent;
354             }
355              
356             sub _index_message1 {
357 170     170   375 my ($index, $dataref) = @_;
358 170         1054 my $method = (caller(1))[3];
359             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: $!"
360             unless (
361             $index =~ /^\d+$/
362 170 100 100     2736 and $index <= ${$dataref}{'maxindex'}
  162         1056  
363             );
364             }
365              
366             sub _index_message2 {
367 135     135   249 my $dataref = shift;
368 135         224 my ($index_left, $index_right);
369 135         713 my $method = (caller(1))[3];
370 135 100 100     2101 croak "Method $method requires 2 arguments: $!"
371             unless (@_ == 0 || @_ == 2);
372 123 100       340 if (@_ == 0) {
373 18         56 $index_left = 0;
374 18         39 $index_right = 1;
375             } else {
376 105         219 ($index_left, $index_right) = @_;
377 105         237 foreach ($index_left, $index_right) {
378             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: $!"
379             unless (
380             $_ =~ /^\d+$/
381 199 100 100     1296 and $_ <= ${$dataref}{'maxindex'}
  196         1514  
382             );
383             }
384             }
385 112         397 return ($index_left, $index_right);
386             }
387              
388             sub _index_message3 {
389 170     170   551 my ($index, $maxindex) = @_;
390 170         943 my $method = (caller(1))[3];
391 170 100 100     3397 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: $!"
392             unless (
393             $index =~ /^\d+$/
394             and $index <= $maxindex
395             );
396             }
397              
398             sub _index_message4 {
399 126     126   292 my $maxindex = shift;
400 126         208 my ($index_left, $index_right);
401 126         610 my $method = (caller(1))[3];
402 126 100 100     2271 croak "Method $method requires 2 arguments: $!"
403             unless (@_ == 0 || @_ == 2);
404 114 100       292 if (@_ == 0) {
405 16         40 $index_left = 0;
406 16         35 $index_right = 1;
407             } else {
408 98         195 ($index_left, $index_right) = @_;
409 98         207 foreach ($index_left, $index_right) {
410 186 100 100     2223 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: $!"
411             unless (
412             $_ =~ /^\d+$/
413             and $_ <= $maxindex
414             );
415             }
416             }
417 104         337 return ($index_left, $index_right);
418             }
419              
420             sub _prepare_listrefs {
421 752     752   1211 my $dataref = shift;
422 752         1081 delete ${$dataref}{'unsort'};
  752         1447  
423 752         1150 my (@listrefs);
424 752         1058 foreach my $lref (sort {$a <=> $b} keys %{$dataref}) {
  5535         8991  
  752         2953  
425 3788         5024 push(@listrefs, ${$dataref}{$lref});
  3788         6658  
426             };
427 752         2116 return \@listrefs;
428             }
429              
430             sub _subset_engine_multaccel {
431 64     64   129 my $dataref = shift;
432 64         205 my $aref = _prepare_listrefs($dataref);
433 64         116 my ($index_left, $index_right) = _index_message4($#{$aref}, @_);
  64         215  
434              
435 56         154 my $xsubsetref = _subset_subengine($aref);
436 56         95 return ${$xsubsetref}[$index_left][$index_right];
  56         276  
437             }
438              
439             sub _calc_seen {
440 718     718   1307 my ($refL, $refR) = @_;
441             # We've already guaranteed that args are both array refs or both hash
442             # refs. So checking the left-hand one is sufficient.
443 718 100       1752 if (ref($refL) eq 'ARRAY') {
444 365         565 my (%seenL, %seenR);
445 365         729 foreach (@$refL) { $seenL{$_}++ }
  2717         4520  
446 365         603 foreach (@$refR) { $seenR{$_}++ }
  2683         4191  
447 365         1224 return (\%seenL, \%seenR);
448             } else {
449 353         965 return ($refL, $refR);
450             }
451             }
452              
453             sub _equiv_engine {
454 56     56   107 my ($hrefL, $hrefR) = @_;
455 56         99 my (%intersection, %Lonly, %Ronly, %LorRonly);
456 56         101 my $LequivalentR_status = 0;
457              
458 56         95 foreach (keys %{$hrefL}) {
  56         177  
459 312 100       433 exists ${$hrefR}{$_} ? $intersection{$_}++ : $Lonly{$_}++;
  312         673  
460             }
461              
462 56         103 foreach (keys %{$hrefR}) {
  56         182  
463 296 100       600 $Ronly{$_}++ unless (exists $intersection{$_});
464             }
465              
466 56         224 $LorRonly{$_}++ foreach ( (keys %Lonly), (keys %Ronly) );
467 56 100       170 $LequivalentR_status = 1 if ( (keys %LorRonly) == 0);
468 56         258 return $LequivalentR_status;
469             }
470              
471             sub _argument_checker_0 {
472 889     889   1690 my @args = @_;
473 889         1586 my $first_ref = ref($args[0]);
474 889         2179 my @temp = @args[1..$#args];
475 889         1379 my ($testing);
476 889         1352 my $condition = 1;
477 889         2011 while (defined ($testing = shift(@temp)) ) {
478 2083 100       5117 unless (ref($testing) eq $first_ref) {
479 18         26 $condition = 0;
480 18         32 last;
481             }
482             }
483 889 100       3618 croak "Arguments must be either all array references or all hash references: $!"
484             unless $condition;
485 871 100       2306 _validate_seen_hash(@args) if $first_ref eq 'HASH';
486 849         2284 return (@args);
487             }
488              
489             sub _argument_checker {
490 842     842   1293 my $argref = shift;
491 842 100       5559 croak "'$argref' must be an array ref" unless ref($argref) eq 'ARRAY';
492 806         1147 my @args = _argument_checker_0(@{$argref});
  806         1665  
493 770         2574 return (@args);
494             }
495              
496             sub _argument_checker_1 {
497 267     267   373 my $argref = shift;
498 267         368 my @args = @{$argref};
  267         430  
499 267 100       834 croak "Subroutine call requires 2 references as arguments: $!"
500             unless @args == 2;
501 264         485 return (_argument_checker($args[0]), ${$args[1]}[0]);
  264         824  
502             }
503              
504             sub _argument_checker_2 {
505 18     18   35 my $argref = shift;
506 18         41 my @args = @$argref;
507 18 100       244 croak "Subroutine call requires 2 references as arguments: $!"
508             unless @args == 2;
509 16         56 return (_argument_checker($args[0]), $args[1]);
510             }
511              
512             # _argument_checker_3 is currently set-up to handle either 1 or 2 arguments
513             # in get_unique and get_complement
514             # The first argument is an arrayref holding refs to lists ('unsorted' has been
515             # stripped off).
516             # The second argument is an arrayref holding a single item (index number of
517             # item being tested)
518             # Note: Currently we're only checking for the quantity of arguments -- not
519             # their types. This should be fixed.
520             sub _argument_checker_3 {
521 115     115   263 my $argref = shift;
522 115         185 my @args = @{$argref};
  115         249  
523 115 100       334 if (@args == 1) {
    100          
524 65         183 return (_argument_checker($args[0]), 0);
525             } elsif (@args == 2) {
526 40         136 return (_argument_checker($args[0]), ${$args[1]}[0]);
  32         173  
527             } else {
528 10         1105 croak "Subroutine call requires 1 or 2 references as arguments: $!";
529             }
530             }
531              
532             sub _argument_checker_3a {
533 34     34   79 my $argref = shift;
534 34         72 my @args = @{$argref};
  34         92  
535 34 100       141 if (@args == 1) {
536 32         97 return [ _argument_checker($args[0]) ];
537             } else {
538 2         278 croak "Subroutine call requires exactly 1 reference as argument: $!";
539             }
540             }
541              
542             sub _argument_checker_4 {
543 136     136   232 my $argref = shift;
544 136         232 my @args = @{$argref};
  136         275  
545 136 100       361 if (@args == 1) {
    100          
546 84         216 return (_argument_checker($args[0]), [0,1]);
547             } elsif (@args == 2) {
548 49 100       72 if (@{$args[1]} == 2) {
  49         114  
549 44         64 my $last_index = $#{$args[0]};
  44         88  
550 44         75 foreach my $i (@{$args[1]}) {
  44         129  
551 80 100 100     1375 croak "No element in index position $i in list of list references passed as first argument to function: $!"
552             unless ($i =~ /^\d+$/ and $i <= $last_index);
553             }
554 36         102 return (_argument_checker($args[0]), $args[1]);
555             } else {
556 5         475 croak "Must provide index positions corresponding to two lists: $!";
557             }
558             } else {
559 3         414 croak "Subroutine call requires 1 or 2 references as arguments: $!";
560             }
561             }
562              
563             sub _calc_seen1 {
564 706     706   1394 my @listrefs = @_;
565             # _calc_seen1() is applied after _argument_checker(), which checks to make
566             # sure that the references in its output are either all arrayrefs
567             # or all seenhashrefs
568             # hence, _calc_seen1 only needs to determine whether it's dealing with
569             # arrayrefs or seenhashrefs, then, if arrayrefs, calculate seenhashes
570 706 100       1502 if (ref($listrefs[0]) eq 'ARRAY') {
571 368         548 my (@seenrefs);
572 368         621 foreach my $aref (@listrefs) {
573 1250         1633 my (%seenthis);
574 1250         1574 foreach my $j (@{$aref}) {
  1250         1908  
575 8088         12473 $seenthis{$j}++;
576             }
577 1250         2388 push(@seenrefs, \%seenthis);
578             }
579 368         1047 return \@seenrefs;
580             } else {
581 338         930 return \@listrefs;
582             }
583             }
584              
585             # _alt_construct_tester prepares for _argument_checker in
586             # get_union get_intersection get_symmetric_difference get_shared get_nonintersection
587             sub _alt_construct_tester {
588 317     317   771 my @args = @_;
589 317         549 my ($argref, $unsorted);
590 317 100 100     1588 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
591 144         280 my $hashref = shift;
592             croak "$bad_lists_msg: $!"
593 144         1923 unless ( ${$hashref}{'lists'}
594 144 100 100     207 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  130         1797  
595 116         207 $argref = ${$hashref}{'lists'};
  116         202  
596 116 100       171 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  116         279  
597             } else {
598 173 100 100     734 $unsorted = shift(@args)
599             if ($args[0] eq '-u' or $args[0] eq '--unsorted');
600 173         350 $argref = shift(@args);
601             }
602 289         918 return ($argref, $unsorted);
603             }
604              
605             # _alt_construct_tester_1 prepares for _argument_checker_1 in
606             # is_member_which is_member_which_ref is_member_any
607             sub _alt_construct_tester_1 {
608 276     276   536 my @args = @_;
609 276         437 my ($argref);
610 276 100 100     899 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
611 119         173 my (@returns);
612 119         166 my $hashref = $args[0];
613             croak "$bad_lists_msg: $!"
614 119         572 unless ( ${$hashref}{'lists'}
615 119 100 100     179 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  116         599  
616             croak "If argument is single hash ref, you must have an 'item' key: $!"
617 113 100       180 unless ${$hashref}{'item'};
  113         508  
618 110         153 @returns = ( ${$hashref}{'lists'}, [${$hashref}{'item'}] );
  110         193  
  110         261  
619 110         209 $argref = \@returns;
620             } else {
621 157         246 $argref = \@args;
622             }
623 267         580 return $argref;
624             }
625              
626             # _alt_construct_tester_2 prepares for _argument_checker_2 in
627             # are_members_which are_members_any
628             sub _alt_construct_tester_2 {
629 26     26   74 my @args = @_;
630 26 100 100     150 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
631 16         34 my $hashref = $args[0];
632             croak "$bad_lists_msg: $!"
633 16         264 unless ( ${$hashref}{'lists'}
634 16 100 100     22 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  14         265  
635             croak "If argument is single hash ref, you must have an 'items' key whose value is an array ref: $!"
636 12         236 unless ( ${$hashref}{'items'}
637 12 100 100     26 and (ref(${$hashref}{'items'}) eq 'ARRAY') );
  10         228  
638 8         16 return [ (${$hashref}{'lists'}, ${$hashref}{'items'}) ];
  8         19  
  8         30  
639             } else {
640 10         33 return \@args;
641             }
642             }
643              
644             # _alt_construct_tester_3 prepares for _argument_checker_3 in
645             # get_unique get_complement
646             sub _alt_construct_tester_3 {
647 157     157   424 my @args = @_;
648 157         344 my ($argref, $unsorted);
649 157 100 100     825 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
650 68         121 my (@returns);
651 68         119 my $hashref = $args[0];
652             croak "$bad_lists_msg: $!"
653 68         612 unless ( ${$hashref}{'lists'}
654 68 100 100     180 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  64         603  
655 60         139 @returns = defined ${$hashref}{'item'}
656 16         30 ? (${$hashref}{'lists'}, [${$hashref}{'item'}])
  16         39  
657 60 100       111 : (${$hashref}{'lists'});
  44         102  
658 60         111 $argref = \@returns;
659 60 100       102 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  60         164  
660             } else {
661 89 100 100     381 $unsorted = shift(@args) if ($args[0] eq '-u' or $args[0] eq '--unsorted');
662 89         250 $argref = \@args;
663             }
664 149         504 return ($argref, $unsorted);
665             }
666              
667             # _alt_construct_tester_4 prepares for _argument_checker_4 in
668             # is_LsubsetR is_RsubsetL is_LequivalentR is_LdisjointR
669             sub _alt_construct_tester_4 {
670 146     146   369 my @args = @_;
671 146         227 my ($argref);
672 146 100 100     726 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
673 70         116 my (@returns);
674 70         152 my $hashref = $args[0];
675             croak "$bad_lists_msg: $!"
676 70         718 unless ( ${$hashref}{'lists'}
677 70 100 100     99 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  65         672  
678 60         141 @returns = defined ${$hashref}{'pair'}
679 18         30 ? (${$hashref}{'lists'}, ${$hashref}{'pair'})
  18         38  
680 60 100       102 : (${$hashref}{'lists'});
  42         90  
681 60         128 $argref = \@returns;
682             } else {
683 76         140 $argref = \@args;
684             }
685 136         351 return $argref;
686             }
687              
688             # _alt_construct_tester_5 prepares for _argument_checker in
689             # print_subset_chart print_equivalence_chart
690             sub _alt_construct_tester_5 {
691 22     22   60 my @args = @_;
692 22         70 my ($argref);
693 22 100       89 if (@args == 1) {
694 20 100       117 if (ref($args[0]) eq 'HASH') {
695 12         27 my $hashref = shift;
696             croak "Need to define 'lists' key properly: $!"
697 12         331 unless ( ${$hashref}{'lists'}
698 12 100 100     19 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  10         383  
699 8         17 $argref = ${$hashref}{'lists'};
  8         21  
700             } else {
701 8         19 $argref = shift(@args);
702             }
703             } else {
704 2         198 croak "Subroutine call requires exactly 1 reference as argument: $!";
705             }
706 16         56 return $argref;
707             }
708              
709             1;
710              
711             __END__