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.54;
3 52     52   364 use Carp;
  52         111  
  52         8095  
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   380 use strict;
  52         109  
  52         277463  
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   61 my ($refL, $refR) = @_;
76 27         54 my (%seenL, %seenR, %badentriesL, %badentriesR);
77 27         110 foreach (keys %$refL) {
78 144 100 100     200 if (${$refL}{$_} =~ /^\d+$/ and ${$refL}{$_} > 0) {
  144         613  
  143         392  
79 142         195 $seenL{$_} = ${$refL}{$_};
  142         356  
80             } else {
81 2         4 $badentriesL{$_} = ${$refL}{$_};
  2         6  
82             }
83             }
84 27         119 foreach (keys %$refR) {
85 133 100 100     187 if (${$refR}{$_} =~ /^\d+$/ and ${$refR}{$_} > 0) {
  133         489  
  132         335  
86 131         204 $seenR{$_} = ${$refR}{$_};
  131         283  
87             } else {
88 2         4 $badentriesR{$_} = ${$refR}{$_};
  2         6  
89             }
90             }
91 27         69 my $msg = q{};
92 27 100 100     155 if ( (keys %badentriesL) or (keys %badentriesR) ) {
93 4         9 $msg .= "\nValues in a 'seen-hash' may only be positive integers.\n";
94 4         7 $msg .= " These elements have invalid values:\n";
95 4 100       10 if (keys %badentriesL) {
96 2         3 $msg .= " First hash in arguments:\n";
97             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
98 2         12 foreach (sort keys %badentriesL);
99             }
100 4 100       14 if (keys %badentriesR) {
101 2         4 $msg .= " Second hash in arguments:\n";
102             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
103 2         10 foreach (sort keys %badentriesR);
104             }
105 4         8 $msg .= "Correct invalid values before proceeding";
106 4         515 croak "$msg: $!";
107             }
108 23         112 return (\%seenL, \%seenR);
109             }
110              
111             sub _validate_seen_hash {
112 441 100   441   977 if (@_ > 2) {
113 206         538 _validate_multiple_seenhashes( [@_] );
114             } else {
115 235         436 my ($l, $r) = @_;
116 235         343 my (%badentriesL, %badentriesR);
117 235         756 foreach (keys %$l) {
118 20         55 $badentriesL{$_} = ${$l}{$_}
119 1450 100 100     1923 unless (${$l}{$_} =~ /^\d+$/ and ${$l}{$_} > 0);
  1450         4529  
  1431         4115  
120             }
121 235         728 foreach (keys %$r) {
122 20         52 $badentriesR{$_} = ${$r}{$_}
123 1423 100 100     1910 unless (${$r}{$_} =~ /^\d+$/ and ${$r}{$_} > 0);
  1423         3762  
  1404         3945  
124             }
125 235         478 my $msg = q{};
126 235 100 100     1033 if ( (keys %badentriesL) or (keys %badentriesR) ) {
127 22         48 $msg .= "\nValues in a 'seen-hash' must be numeric.\n";
128 22         36 $msg .= " These elements have invalid values:\n";
129 22 100       51 if (keys %badentriesL) {
130 20         32 $msg .= " First hash in arguments:\n";
131             $msg .= " Key: $_\tValue: $badentriesL{$_}\n"
132 20         93 foreach (sort keys %badentriesL);
133             }
134 22 100       53 if (keys %badentriesR) {
135 20         40 $msg .= " Second hash in arguments:\n";
136             $msg .= " Key: $_\tValue: $badentriesR{$_}\n"
137 20         68 foreach (sort keys %badentriesR);
138             }
139 22         44 $msg .= "Correct invalid values before proceeding";
140 22         2368 croak "$msg: $!";
141             }
142             }
143             }
144              
145             sub _validate_multiple_seenhashes {
146 206     206   336 my $hashrefsref = shift;
147 206         312 my (%badentries);
148 206         365 for (my $i = 0; $i <= $#{$hashrefsref}; $i++) {
  1246         2608  
149 1040         1418 foreach my $k (keys %{$hashrefsref->[$i]}) {
  1040         2604  
150 5588 100 100     22736 unless ($hashrefsref->[$i]->{$k} =~ /^\d+$/ and $hashrefsref->[$i]->{$k} > 0) {
151 2         7 $badentries{$i}{$k} = $hashrefsref->[$i]->{$k};
152             }
153             }
154             }
155 206         396 my $msg = q{};
156 206 100       685 if (scalar(keys %badentries)) {
157 2         3 $msg .= "\nValues in a 'seen-hash' must be positive integers.\n";
158 2         4 $msg .= " These elements have invalid values:\n\n";
159 2         7 foreach my $b (sort keys %badentries) {
160 2         7 $msg .= " Hash $b:\n";
161 2         5 foreach my $val (sort keys %{$badentries{$b}}) {
  2         5  
162 2         11 $msg .= " Bad key-value pair: $val\t$badentries{$b}->{$val}\n";
163             }
164             }
165 2         5 $msg .= "Correct invalid values before proceeding";
166 2         210 croak "$msg: $!";
167             }
168             }
169              
170             sub _list_builder {
171 6052     6052   10368 my ($aref, $x) = @_;
172 6052 100       8587 if (ref(${$aref}[$x]) eq 'HASH') {
  6052         12889  
173 4072         5596 return keys %{${$aref}[$x]};
  4072         5286  
  4072         13063  
174             } else {
175 1980         2722 return @{${$aref}[$x]};
  1980         2522  
  1980         5825  
176             }
177             }
178              
179             sub _calculate_array_seen_only {
180 136     136   253 my $aref = shift;
181 136         219 my (@seen);
182 136         247 for (my $i = 0; $i <= $#{$aref}; $i++) {
  744         1606  
183 608         907 my %seenthis = ();
184 608         1013 foreach my $el ( _list_builder($aref, $i) ) {
185 3564         5650 $seenthis{$el}++;
186             }
187 608         1397 push @seen, \%seenthis;
188             }
189 136         342 return \@seen;
190             }
191              
192             sub _calculate_seen_only {
193 901     901   1492 my $aref = shift;
194 901         1418 my (%seen);
195 901         1601 for (my $i = 0; $i <= $#{$aref}; $i++) {
  4687         9973  
196 3786         5715 my %seenthis = ();
197 3786         6747 foreach my $h ( _list_builder($aref, $i) ) {
198 21918         35262 $seenthis{$h}++;
199             }
200 3786         9111 $seen{$i} = \%seenthis;
201             }
202 901         2842 return \%seen;
203             }
204              
205             sub _calculate_intermediate {
206 32     32   82 my $aref = shift;
207 32         88 my $aseenref = _calculate_array_seen_only($aref);
208 32         65 my @vals = sort { scalar(keys(%{$a})) <=> scalar(keys(%{$b})) } @{$aseenref};
  192         278  
  192         306  
  192         379  
  32         147  
209 32         72 my %intermediate = map { $_ => 1 } keys %{$vals[0]};
  128         283  
  32         110  
210 32         132 for my $l ( 1..$#vals ) {
211 384         843 %intermediate = map { $_ => 1 }
212 736         1276 grep { exists $intermediate{$_} }
213 128         200 keys %{$vals[$l]};
  128         304  
214             }
215 32         192 return \%intermediate;
216             }
217              
218             sub _calculate_union_only {
219 225     225   399 my $aref = shift;
220 225         368 my (%union);
221 225         439 for (my $i = 0; $i <= $#{$aref}; $i++) {
  1155         2527  
222 930         1791 foreach my $h ( _list_builder($aref, $i) ) {
223 5470         9453 $union{$h}++;
224             }
225             }
226 225         692 return \%union;
227             }
228              
229             sub _calculate_union_seen_only {
230 160     160   316 my $aref = shift;
231 160         298 my (%union, %seen);
232 160         345 for (my $i = 0; $i <= $#{$aref}; $i++) {
  888         2081  
233 728         1107 my %seenthis = ();
234 728         1329 foreach my $h ( _list_builder($aref, $i) ) {
235 4276         6529 $seenthis{$h}++;
236 4276         6549 $union{$h}++;
237             }
238 728         1896 $seen{$i} = \%seenthis;
239             }
240 160         598 return (\%union, \%seen);
241             }
242              
243             sub _calculate_sharedref {
244 176     176   320 my $seenrefsref = shift;
245              
246 176         339 my %intermediate = ();
247 176         295 for my $href (@{$seenrefsref}) {
  176         358  
248 736         1040 my %this = map { $_ => 1 } keys(%{$href});
  4128         7475  
  736         1860  
249 736         2040 for my $k (keys %this) {;
250 4128         7030 $intermediate{$k}++;
251             };
252             }
253              
254 176         311 my $sharedref;
255 176         603 for my $k (keys %intermediate) {
256 1664 100       3688 $sharedref->{$k}++ if $intermediate{$k} > 1;
257             }
258 176         667 return $sharedref;
259             }
260              
261             sub _is_list_subset {
262 1364     1364   2246 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     6148 $superset->{ $_ } or return 0 for keys %$subset;
269 440         1011 return 1;
270             }
271              
272             sub _subset_subengine {
273 204     204   340 my $aref = shift;
274 204         323 my (@xsubset);
275 204         322 my %seen = %{_calculate_seen_only($aref)};
  204         445  
276 204         778 foreach my $i (keys %seen) {
277 796         1733 foreach my $j (keys %seen) {
278 3524 100       7526 if ( $i eq $j ) {
    100          
279 796         1780 $xsubset[$i][$j] = 1;
280             }
281             elsif ( $i gt $j ) {
282 1364 100       1884 if ( scalar(keys %{ $seen{$i} }) == scalar(keys %{ $seen{$j} }) ){
  1364 100       2316  
  1364         2850  
283 300         647 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
284 300         750 $xsubset[$j][$i] = $xsubset[$i][$j];
285             }
286 1064         1635 elsif ( scalar(keys %{ $seen{$i} }) < scalar(keys %{ $seen{$j} }) ){
  1064         1918  
287 1052         1901 $xsubset[$i][$j] = _is_list_subset($seen{$i}, $seen{$j});
288 1052         2357 $xsubset[$j][$i] = 0;
289             }
290             else {
291 12         28 $xsubset[$j][$i] = _is_list_subset($seen{$j}, $seen{$i});
292 12         27 $xsubset[$i][$j] = 0;
293             }
294             }
295             }
296             }
297 204         1112 return \@xsubset;
298             }
299             sub _chart_engine_regular {
300 32     32   73 my $aref = shift;
301 32         89 my @sub_or_eqv = @$aref;
302 32         75 my $title = shift;
303 32         72 my ($v, $w, $t);
304 32         1056 print "\n";
305 32         404 print $title, ' Relationships', "\n\n";
306 32         358 print ' Right: 0 1', "\n\n";
307 32         662 print 'Left: 0: 1 ', $sub_or_eqv[0], "\n\n";
308 32         653 print ' 1: ', $sub_or_eqv[1], ' 1', "\n\n";
309             }
310              
311             sub _chart_engine_multiple {
312 48     48   133 my $aref = shift;
313 48         148 my @sub_or_eqv = @$aref;
314 48         103 my $title = shift;
315 48         122 my ($v, $w, $t);
316 48         1711 print "\n";
317 48         708 print $title, ' Relationships', "\n\n";
318 48         517 print ' Right:';
319 48         368 for ($v = 0; $v <= $#sub_or_eqv; $v++) {
320 216         2826 print ' ', $v;
321             }
322 48         546 print "\n\n";
323 48         506 print 'Left: 0:';
324 48         188 my @firstrow = @{$sub_or_eqv[0]};
  48         213  
325 48         279 for ($t = 0; $t <= $#firstrow; $t++) {
326 216         2697 print ' ', $firstrow[$t];
327             }
328 48         512 print "\n\n";
329 48         342 for ($w = 1; $w <= $#sub_or_eqv; $w++) {
330 168         480 my $length_left = length($w);
331 168         265 my $x = '';
332 168         1658 print ' ' x (8 - $length_left), $w, ':';
333 168         451 my @row = @{$sub_or_eqv[$w]};
  168         515  
334 168         576 for ($x = 0; $x <= $#row; $x++) {
335 816         9956 print ' ', $row[$x];
336             }
337 168         1984 print "\n\n";
338             }
339 48         588 1; # force return true value
340             }
341              
342             sub _equivalent_subengine {
343 76     76   146 my $aref = shift;
344 76         121 my @xsubset = @{_subset_subengine($aref)};
  76         167  
345 76         212 my (@xequivalent);
346 76         242 for (my $f = 0; $f <= $#xsubset; $f++) {
347 296         594 for (my $g = 0; $g <= $#xsubset; $g++) {
348 1312         1929 $xequivalent[$f][$g] = 0;
349 1312 100 100     3779 $xequivalent[$f][$g] = 1
350             if ($xsubset[$f][$g] and $xsubset[$g][$f]);
351             }
352             }
353 76         326 return \@xequivalent;
354             }
355              
356             sub _index_message1 {
357 170     170   377 my ($index, $dataref) = @_;
358 170         987 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     2844 and $index <= ${$dataref}{'maxindex'}
  162         1027  
363             );
364             }
365              
366             sub _index_message2 {
367 135     135   246 my $dataref = shift;
368 135         230 my ($index_left, $index_right);
369 135         658 my $method = (caller(1))[3];
370 135 100 100     2295 croak "Method $method requires 2 arguments: $!"
371             unless (@_ == 0 || @_ == 2);
372 123 100       459 if (@_ == 0) {
373 18         51 $index_left = 0;
374 18         39 $index_right = 1;
375             } else {
376 105         239 ($index_left, $index_right) = @_;
377 105         231 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     1192 and $_ <= ${$dataref}{'maxindex'}
  196         1413  
382             );
383             }
384             }
385 112         396 return ($index_left, $index_right);
386             }
387              
388             sub _index_message3 {
389 170     170   557 my ($index, $maxindex) = @_;
390 170         940 my $method = (caller(1))[3];
391 170 100 100     3464 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   301 my $maxindex = shift;
400 126         247 my ($index_left, $index_right);
401 126         619 my $method = (caller(1))[3];
402 126 100 100     2194 croak "Method $method requires 2 arguments: $!"
403             unless (@_ == 0 || @_ == 2);
404 114 100       324 if (@_ == 0) {
405 16         39 $index_left = 0;
406 16         41 $index_right = 1;
407             } else {
408 98         210 ($index_left, $index_right) = @_;
409 98         201 foreach ($index_left, $index_right) {
410 186 100 100     2342 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         447 return ($index_left, $index_right);
418             }
419              
420             sub _prepare_listrefs {
421 752     752   1308 my $dataref = shift;
422 752         1106 delete ${$dataref}{'unsort'};
  752         1601  
423 752         1234 my (@listrefs);
424 752         1137 foreach my $lref (sort {$a <=> $b} keys %{$dataref}) {
  5690         9727  
  752         3249  
425 3788         5134 push(@listrefs, ${$dataref}{$lref});
  3788         7244  
426             };
427 752         2236 return \@listrefs;
428             }
429              
430             sub _subset_engine_multaccel {
431 64     64   123 my $dataref = shift;
432 64         146 my $aref = _prepare_listrefs($dataref);
433 64         121 my ($index_left, $index_right) = _index_message4($#{$aref}, @_);
  64         238  
434              
435 56         188 my $xsubsetref = _subset_subengine($aref);
436 56         94 return ${$xsubsetref}[$index_left][$index_right];
  56         282  
437             }
438              
439             sub _calc_seen {
440 718     718   1259 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       1619 if (ref($refL) eq 'ARRAY') {
444 365         509 my (%seenL, %seenR);
445 365         651 foreach (@$refL) { $seenL{$_}++ }
  2717         4127  
446 365         566 foreach (@$refR) { $seenR{$_}++ }
  2683         3796  
447 365         1089 return (\%seenL, \%seenR);
448             } else {
449 353         990 return ($refL, $refR);
450             }
451             }
452              
453             sub _equiv_engine {
454 56     56   103 my ($hrefL, $hrefR) = @_;
455 56         106 my (%intersection, %Lonly, %Ronly, %LorRonly);
456 56         87 my $LequivalentR_status = 0;
457              
458 56         99 foreach (keys %{$hrefL}) {
  56         176  
459 312 100       388 exists ${$hrefR}{$_} ? $intersection{$_}++ : $Lonly{$_}++;
  312         716  
460             }
461              
462 56         111 foreach (keys %{$hrefR}) {
  56         139  
463 296 100       587 $Ronly{$_}++ unless (exists $intersection{$_});
464             }
465              
466 56         174 $LorRonly{$_}++ foreach ( (keys %Lonly), (keys %Ronly) );
467 56 100       173 $LequivalentR_status = 1 if ( (keys %LorRonly) == 0);
468 56         268 return $LequivalentR_status;
469             }
470              
471             sub _argument_checker_0 {
472 889     889   1756 my @args = @_;
473 889         1583 my $first_ref = ref($args[0]);
474 889         2180 my @temp = @args[1..$#args];
475 889         1377 my ($testing);
476 889         1347 my $condition = 1;
477 889         2077 while (defined ($testing = shift(@temp)) ) {
478 2083 100       5277 unless (ref($testing) eq $first_ref) {
479 18         30 $condition = 0;
480 18         37 last;
481             }
482             }
483 889 100       3685 croak "Arguments must be either all array references or all hash references: $!"
484             unless $condition;
485 871 100       2351 _validate_seen_hash(@args) if $first_ref eq 'HASH';
486 849         2255 return (@args);
487             }
488              
489             sub _argument_checker {
490 842     842   1323 my $argref = shift;
491 842 100       5520 croak "'$argref' must be an array ref" unless ref($argref) eq 'ARRAY';
492 806         1252 my @args = _argument_checker_0(@{$argref});
  806         1644  
493 770         2990 return (@args);
494             }
495              
496             sub _argument_checker_1 {
497 267     267   398 my $argref = shift;
498 267         379 my @args = @{$argref};
  267         503  
499 267 100       865 croak "Subroutine call requires 2 references as arguments: $!"
500             unless @args == 2;
501 264         508 return (_argument_checker($args[0]), ${$args[1]}[0]);
  264         901  
502             }
503              
504             sub _argument_checker_2 {
505 18     18   38 my $argref = shift;
506 18         45 my @args = @$argref;
507 18 100       266 croak "Subroutine call requires 2 references as arguments: $!"
508             unless @args == 2;
509 16         60 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   271 my $argref = shift;
522 115         174 my @args = @{$argref};
  115         253  
523 115 100       350 if (@args == 1) {
    100          
524 65         202 return (_argument_checker($args[0]), 0);
525             } elsif (@args == 2) {
526 40         120 return (_argument_checker($args[0]), ${$args[1]}[0]);
  32         187  
527             } else {
528 10         1148 croak "Subroutine call requires 1 or 2 references as arguments: $!";
529             }
530             }
531              
532             sub _argument_checker_3a {
533 34     34   71 my $argref = shift;
534 34         63 my @args = @{$argref};
  34         125  
535 34 100       115 if (@args == 1) {
536 32         98 return [ _argument_checker($args[0]) ];
537             } else {
538 2         333 croak "Subroutine call requires exactly 1 reference as argument: $!";
539             }
540             }
541              
542             sub _argument_checker_4 {
543 136     136   235 my $argref = shift;
544 136         204 my @args = @{$argref};
  136         281  
545 136 100       352 if (@args == 1) {
    100          
546 84         218 return (_argument_checker($args[0]), [0,1]);
547             } elsif (@args == 2) {
548 49 100       106 if (@{$args[1]} == 2) {
  49         121  
549 44         102 my $last_index = $#{$args[0]};
  44         105  
550 44         81 foreach my $i (@{$args[1]}) {
  44         125  
551 80 100 100     1366 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         139 return (_argument_checker($args[0]), $args[1]);
555             } else {
556 5         516 croak "Must provide index positions corresponding to two lists: $!";
557             }
558             } else {
559 3         324 croak "Subroutine call requires 1 or 2 references as arguments: $!";
560             }
561             }
562              
563             sub _calc_seen1 {
564 706     706   1487 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       1549 if (ref($listrefs[0]) eq 'ARRAY') {
571 368         533 my (@seenrefs);
572 368         642 foreach my $aref (@listrefs) {
573 1250         1722 my (%seenthis);
574 1250         1631 foreach my $j (@{$aref}) {
  1250         2037  
575 8088         12961 $seenthis{$j}++;
576             }
577 1250         2515 push(@seenrefs, \%seenthis);
578             }
579 368         1071 return \@seenrefs;
580             } else {
581 338         997 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   742 my @args = @_;
589 317         560 my ($argref, $unsorted);
590 317 100 100     1612 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
591 144         280 my $hashref = shift;
592             croak "$bad_lists_msg: $!"
593 144         1948 unless ( ${$hashref}{'lists'}
594 144 100 100     215 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  130         1794  
595 116         195 $argref = ${$hashref}{'lists'};
  116         196  
596 116 100       180 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  116         280  
597             } else {
598 173 100 100     721 $unsorted = shift(@args)
599             if ($args[0] eq '-u' or $args[0] eq '--unsorted');
600 173         380 $argref = shift(@args);
601             }
602 289         991 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   582 my @args = @_;
609 276         411 my ($argref);
610 276 100 100     945 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
611 119         180 my (@returns);
612 119         211 my $hashref = $args[0];
613             croak "$bad_lists_msg: $!"
614 119         570 unless ( ${$hashref}{'lists'}
615 119 100 100     157 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  116         627  
616             croak "If argument is single hash ref, you must have an 'item' key: $!"
617 113 100       183 unless ${$hashref}{'item'};
  113         508  
618 110         174 @returns = ( ${$hashref}{'lists'}, [${$hashref}{'item'}] );
  110         163  
  110         253  
619 110         205 $argref = \@returns;
620             } else {
621 157         265 $argref = \@args;
622             }
623 267         584 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   118 my @args = @_;
630 26 100 100     160 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
631 16         32 my $hashref = $args[0];
632             croak "$bad_lists_msg: $!"
633 16         265 unless ( ${$hashref}{'lists'}
634 16 100 100     32 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  14         254  
635             croak "If argument is single hash ref, you must have an 'items' key whose value is an array ref: $!"
636 12         242 unless ( ${$hashref}{'items'}
637 12 100 100     25 and (ref(${$hashref}{'items'}) eq 'ARRAY') );
  10         227  
638 8         21 return [ (${$hashref}{'lists'}, ${$hashref}{'items'}) ];
  8         13  
  8         34  
639             } else {
640 10         43 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   445 my @args = @_;
648 157         356 my ($argref, $unsorted);
649 157 100 100     863 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
650 68         126 my (@returns);
651 68         115 my $hashref = $args[0];
652             croak "$bad_lists_msg: $!"
653 68         618 unless ( ${$hashref}{'lists'}
654 68 100 100     177 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  64         618  
655 60         141 @returns = defined ${$hashref}{'item'}
656 16         35 ? (${$hashref}{'lists'}, [${$hashref}{'item'}])
  16         42  
657 60 100       104 : (${$hashref}{'lists'});
  44         107  
658 60         128 $argref = \@returns;
659 60 100       88 $unsorted = ${$hashref}{'unsorted'} ? 1 : '';
  60         158  
660             } else {
661 89 100 100     386 $unsorted = shift(@args) if ($args[0] eq '-u' or $args[0] eq '--unsorted');
662 89         256 $argref = \@args;
663             }
664 149         558 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   394 my @args = @_;
671 146         231 my ($argref);
672 146 100 100     719 if (@args == 1 and (ref($args[0]) eq 'HASH')) {
673 70         122 my (@returns);
674 70         120 my $hashref = $args[0];
675             croak "$bad_lists_msg: $!"
676 70         754 unless ( ${$hashref}{'lists'}
677 70 100 100     120 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  65         678  
678 60         138 @returns = defined ${$hashref}{'pair'}
679 18         44 ? (${$hashref}{'lists'}, ${$hashref}{'pair'})
  18         39  
680 60 100       106 : (${$hashref}{'lists'});
  42         122  
681 60         136 $argref = \@returns;
682             } else {
683 76         142 $argref = \@args;
684             }
685 136         353 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   73 my @args = @_;
692 22         76 my ($argref);
693 22 100       79 if (@args == 1) {
694 20 100       120 if (ref($args[0]) eq 'HASH') {
695 12         26 my $hashref = shift;
696             croak "Need to define 'lists' key properly: $!"
697 12         334 unless ( ${$hashref}{'lists'}
698 12 100 100     23 and (ref(${$hashref}{'lists'}) eq 'ARRAY') );
  10         419  
699 8         17 $argref = ${$hashref}{'lists'};
  8         21  
700             } else {
701 8         20 $argref = shift(@args);
702             }
703             } else {
704 2         238 croak "Subroutine call requires exactly 1 reference as argument: $!";
705             }
706 16         52 return $argref;
707             }
708              
709             1;
710              
711             __END__