5 @INC = qw(../lib ../ext/B/t);
15 #examples poached from perldoc -f sort
20 # chunk: # sort lexically
21 @articles = sort @files;
25 checkOptree(note => q{},
27 code => q{@articles = sort @files; },
28 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
29 # 1 <;> nextstate(main 545 (eval 15):1) v
33 # 5 <1> rv2av[t4] lK/1
36 # 8 <#> gv[*articles] s
37 # 9 <1> rv2av[t2] lKRM*/1
38 # a <2> aassign[t5] KS
39 # b <1> leavesub[1 ref] K/REFC,1
41 # 1 <;> nextstate(main 545 (eval 15):1) v
45 # 5 <1> rv2av[t2] lK/1
48 # 8 <$> gv(*articles) s
49 # 9 <1> rv2av[t1] lKRM*/1
50 # a <2> aassign[t3] KS
51 # b <1> leavesub[1 ref] K/REFC,1
57 # chunk: # same thing, but with explicit sort routine
58 @articles = sort {$a cmp $b} @files;
62 checkOptree(note => q{},
64 code => q{@articles = sort {$a cmp $b} @files; },
65 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
66 # 1 <;> nextstate(main 546 (eval 15):1) v
70 # 5 <1> rv2av[t7] lK/1
73 # 8 <#> gv[*articles] s
74 # 9 <1> rv2av[t2] lKRM*/1
75 # a <2> aassign[t5] KS
76 # b <1> leavesub[1 ref] K/REFC,1
78 # 1 <;> nextstate(main 546 (eval 15):1) v
82 # 5 <1> rv2av[t3] lK/1
85 # 8 <$> gv(*articles) s
86 # 9 <1> rv2av[t1] lKRM*/1
87 # a <2> aassign[t2] KS
88 # b <1> leavesub[1 ref] K/REFC,1
94 # chunk: # now case-insensitively
95 @articles = sort {uc($a) cmp uc($b)} @files;
99 checkOptree(note => q{},
101 code => q{@articles = sort {uc($a) cmp uc($b)} @files; },
102 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
103 # 1 <;> nextstate(main 546 (eval 15):1) v
107 # 5 <1> rv2av[t9] lK/1
110 # 8 <#> gv[*articles] s
111 # 9 <1> rv2av[t2] lKRM*/1
112 # a <2> aassign[t10] KS
113 # b <1> leavesub[1 ref] K/REFC,1
115 # 1 <;> nextstate(main 546 (eval 15):1) v
119 # 5 <1> rv2av[t5] lK/1
122 # 8 <$> gv(*articles) s
123 # 9 <1> rv2av[t1] lKRM*/1
124 # a <2> aassign[t6] KS
125 # b <1> leavesub[1 ref] K/REFC,1
131 # chunk: # same thing in reversed order
132 @articles = sort {$b cmp $a} @files;
136 checkOptree(note => q{},
138 code => q{@articles = sort {$b cmp $a} @files; },
139 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
140 # 1 <;> nextstate(main 546 (eval 15):1) v
144 # 5 <1> rv2av[t7] lK/1
147 # 8 <#> gv[*articles] s
148 # 9 <1> rv2av[t2] lKRM*/1
149 # a <2> aassign[t5] KS
150 # b <1> leavesub[1 ref] K/REFC,1
152 # 1 <;> nextstate(main 546 (eval 15):1) v
156 # 5 <1> rv2av[t3] lK/1
159 # 8 <$> gv(*articles) s
160 # 9 <1> rv2av[t1] lKRM*/1
161 # a <2> aassign[t2] KS
162 # b <1> leavesub[1 ref] K/REFC,1
168 # chunk: # sort numerically ascending
169 @articles = sort {$a <=> $b} @files;
173 checkOptree(note => q{},
175 code => q{@articles = sort {$a <=> $b} @files; },
176 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
177 # 1 <;> nextstate(main 546 (eval 15):1) v
181 # 5 <1> rv2av[t7] lK/1
184 # 8 <#> gv[*articles] s
185 # 9 <1> rv2av[t2] lKRM*/1
186 # a <2> aassign[t5] KS
187 # b <1> leavesub[1 ref] K/REFC,1
189 # 1 <;> nextstate(main 546 (eval 15):1) v
193 # 5 <1> rv2av[t3] lK/1
196 # 8 <$> gv(*articles) s
197 # 9 <1> rv2av[t1] lKRM*/1
198 # a <2> aassign[t2] KS
199 # b <1> leavesub[1 ref] K/REFC,1
205 # chunk: # sort numerically descending
206 @articles = sort {$b <=> $a} @files;
210 checkOptree(note => q{},
212 code => q{@articles = sort {$b <=> $a} @files; },
213 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
214 # 1 <;> nextstate(main 587 (eval 26):1) v
218 # 5 <1> rv2av[t7] lK/1
219 # 6 <@> sort lK/REV,NUM
221 # 8 <#> gv[*articles] s
222 # 9 <1> rv2av[t2] lKRM*/1
223 # a <2> aassign[t5] KS
224 # b <1> leavesub[1 ref] K/REFC,1
226 # 1 <;> nextstate(main 546 (eval 15):1) v
230 # 5 <1> rv2av[t3] lK/1
231 # 6 <@> sort lK/REV,NUM
233 # 8 <$> gv(*articles) s
234 # 9 <1> rv2av[t1] lKRM*/1
235 # a <2> aassign[t2] KS
236 # b <1> leavesub[1 ref] K/REFC,1
242 # chunk: # this sorts the %age hash by value instead of key
243 # using an in-line function
244 @eldest = sort { $age{$b} <=> $age{$a} } keys %age;
248 checkOptree(note => q{},
250 code => q{@eldest = sort { $age{$b} <=> $age{$a} } keys %age; },
251 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
252 # 1 <;> nextstate(main 592 (eval 28):1) v
256 # 5 <1> rv2hv[t9] lKRM/1
257 # 6 <1> keys[t10] lK/1
260 # 9 <#> gv[*eldest] s
261 # a <1> rv2av[t2] lKRM*/1
262 # b <2> aassign[t11] KS
263 # c <1> leavesub[1 ref] K/REFC,1
265 # 1 <;> nextstate(main 546 (eval 15):1) v
269 # 5 <1> rv2hv[t3] lKRM/1
270 # 6 <1> keys[t4] lK/1
273 # 9 <$> gv(*eldest) s
274 # a <1> rv2av[t1] lKRM*/1
275 # b <2> aassign[t5] KS
276 # c <1> leavesub[1 ref] K/REFC,1
282 # chunk: # sort using explicit subroutine name
284 $age{$a} <=> $age{$b}; # presuming numeric
286 @sortedclass = sort byage @class;
290 checkOptree(note => q{},
292 code => q{sub byage { $age{$a} <=> $age{$b}; } @sortedclass = sort byage @class; },
293 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
294 # 1 <;> nextstate(main 597 (eval 30):1) v
297 # 4 <$> const[PV "byage"] s/BARE
299 # 6 <1> rv2av[t4] lK/1
302 # 9 <#> gv[*sortedclass] s
303 # a <1> rv2av[t2] lKRM*/1
304 # b <2> aassign[t5] KS
305 # c <1> leavesub[1 ref] K/REFC,1
307 # 1 <;> nextstate(main 546 (eval 15):1) v
310 # 4 <$> const(PV "byage") s/BARE
312 # 6 <1> rv2av[t2] lK/1
315 # 9 <$> gv(*sortedclass) s
316 # a <1> rv2av[t1] lKRM*/1
317 # b <2> aassign[t3] KS
318 # c <1> leavesub[1 ref] K/REFC,1
324 # chunk: sub backwards { $b cmp $a }
325 @harry = qw(dog cat x Cain Abel);
326 @george = qw(gone chased yz Punished Axed);
328 # prints AbelCaincatdogx
329 print sort backwards @harry;
330 # prints xdogcatCainAbel
331 print sort @george, 'to', @harry;
332 # prints AbelAxedCainPunishedcatchaseddoggonetoxyz
336 checkOptree(note => q{},
338 todo => 'sort why BARE flag happens',
339 code => q{sub backwards { $b cmp $a }
340 @harry = qw(dog cat x Cain Abel);
341 @george = qw(gone chased yz Punished Axed);
342 print sort @harry; print sort backwards @harry;
343 print sort @george, 'to', @harry; },
344 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
345 # 1 <;> nextstate(main 602 (eval 32):2) v
347 # 3 <$> const[PV "dog"] s
348 # 4 <$> const[PV "cat"] s
349 # 5 <$> const[PV "x"] s
350 # 6 <$> const[PV "Cain"] s
351 # 7 <$> const[PV "Abel"] s
354 # a <1> rv2av[t2] lKRM*/1
355 # b <2> aassign[t3] vKS
356 # c <;> nextstate(main 602 (eval 32):3) v
358 # e <$> const[PV "gone"] s
359 # f <$> const[PV "chased"] s
360 # g <$> const[PV "yz"] s
361 # h <$> const[PV "Punished"] s
362 # i <$> const[PV "Axed"] s
364 # k <#> gv[*george] s
365 # l <1> rv2av[t5] lKRM*/1
366 # m <2> aassign[t6] vKS
367 # n <;> nextstate(main 602 (eval 32):4) v
371 # r <1> rv2av[t8] lK/1
374 # u <;> nextstate(main 602 (eval 32):4) v
377 # x <$> const[PV "backwards"] s/BARE
379 # z <1> rv2av[t10] lK/1
382 # 12 <;> nextstate(main 602 (eval 32):5) v
385 # 15 <#> gv[*george] s
386 # 16 <1> rv2av[t12] lK/1
387 # 17 <$> const[PV "to"] s
388 # 18 <#> gv[*harry] s
389 # 19 <1> rv2av[t14] lK/1
392 # 1c <1> leavesub[1 ref] K/REFC,1
394 # 1 <;> nextstate(main 602 (eval 32):2) v
396 # 3 <$> const(PV "dog") s
397 # 4 <$> const(PV "cat") s
398 # 5 <$> const(PV "x") s
399 # 6 <$> const(PV "Cain") s
400 # 7 <$> const(PV "Abel") s
403 # a <1> rv2av[t1] lKRM*/1
404 # b <2> aassign[t2] vKS
405 # c <;> nextstate(main 602 (eval 32):3) v
407 # e <$> const(PV "gone") s
408 # f <$> const(PV "chased") s
409 # g <$> const(PV "yz") s
410 # h <$> const(PV "Punished") s
411 # i <$> const(PV "Axed") s
413 # k <$> gv(*george) s
414 # l <1> rv2av[t3] lKRM*/1
415 # m <2> aassign[t4] vKS
416 # n <;> nextstate(main 602 (eval 32):4) v
420 # r <1> rv2av[t5] lK/1
423 # u <;> nextstate(main 602 (eval 32):4) v
426 # x <$> const(PV "backwards") s/BARE
428 # z <1> rv2av[t6] lK/1
431 # 12 <;> nextstate(main 602 (eval 32):5) v
434 # 15 <$> gv(*george) s
435 # 16 <1> rv2av[t7] lK/1
436 # 17 <$> const(PV "to") s
437 # 18 <$> gv(*harry) s
438 # 19 <1> rv2av[t8] lK/1
441 # 1c <1> leavesub[1 ref] K/REFC,1
447 # chunk: # inefficiently sort by descending numeric compare using
448 # the first integer after the first = sign, or the
449 # whole record case-insensitively otherwise
451 $nums[$b] <=> $nums[$a]
452 || $caps[$a] cmp $caps[$b]
458 # chunk: # same thing, but without any temps
459 @new = map { $_->[0] }
460 sort { $b->[1] <=> $a->[1]
461 || $a->[2] cmp $b->[2]
462 } map { [$_, /=(\d+)/, uc($_)] } @old;
466 checkOptree(note => q{},
468 code => q{ @new = map { $_->[0] }
469 sort { $b->[1] <=> $a->[1] || $a->[2] cmp $b->[2] }
470 map { [$_, /=(\d+)/, uc($_)] } @old; },
471 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
472 # 1 <;> nextstate(main 609 (eval 34):3) v
478 # 7 <1> rv2av[t19] lKM/1
480 # 9 <|> mapwhile(other->a)[t20] lK
482 # b <;> nextstate(main 608 (eval 34):2) v
485 # e </> match(/"=(\\d+)"/) l/RTIME
488 # h <@> anonlist sKRM/1
494 # m <|> mapwhile(other->n)[t26] lK
496 # o <1> rv2sv sKM/DREFAV,1
497 # p <1> rv2av[t4] sKR/1
498 # q <$> const[IV 0] s
504 # u <1> rv2av[t2] lKRM*/1
505 # v <2> aassign[t27] KS/COMMON
506 # w <1> leavesub[1 ref] K/REFC,1
508 # 1 <;> nextstate(main 609 (eval 34):3) v
514 # 7 <1> rv2av[t10] lKM/1
516 # 9 <|> mapwhile(other->a)[t11] lK
518 # b <;> nextstate(main 608 (eval 34):2) v
521 # e </> match(/"=(\\d+)"/) l/RTIME
524 # h <@> anonlist sKRM/1
530 # m <|> mapwhile(other->n)[t12] lK
532 # o <1> rv2sv sKM/DREFAV,1
533 # p <1> rv2av[t2] sKR/1
534 # q <$> const(IV 0) s
540 # u <1> rv2av[t1] lKRM*/1
541 # v <2> aassign[t13] KS/COMMON
542 # w <1> leavesub[1 ref] K/REFC,1
548 # chunk: # using a prototype allows you to use any comparison subroutine
549 # as a sort subroutine (including other package's subroutines)
551 sub backwards ($$) { $_[1] cmp $_[0]; } # $a and $b are not set here
553 @new = sort other::backwards @old;
557 checkOptree(note => q{},
559 code => q{package other; sub backwards ($$) { $_[1] cmp $_[0]; }
560 package main; @new = sort other::backwards @old; },
561 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
562 # 1 <;> nextstate(main 614 (eval 36):2) v
565 # 4 <$> const[PV "other::backwards"] s/BARE
567 # 6 <1> rv2av[t4] lK/1
571 # a <1> rv2av[t2] lKRM*/1
572 # b <2> aassign[t5] KS
573 # c <1> leavesub[1 ref] K/REFC,1
575 # 1 <;> nextstate(main 614 (eval 36):2) v
578 # 4 <$> const(PV "other::backwards") s/BARE
580 # 6 <1> rv2av[t2] lK/1
584 # a <1> rv2av[t1] lKRM*/1
585 # b <2> aassign[t3] KS
586 # c <1> leavesub[1 ref] K/REFC,1
592 # chunk: # repeat, condensed. $main::a and $b are unaffected
593 sub other::backwards ($$) { $_[1] cmp $_[0]; }
594 @new = sort other::backwards @old;
598 checkOptree(note => q{},
600 code => q{sub other::backwards ($$) { $_[1] cmp $_[0]; } @new = sort other::backwards @old; },
601 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
602 # 1 <;> nextstate(main 619 (eval 38):1) v
605 # 4 <$> const[PV "other::backwards"] s/BARE
607 # 6 <1> rv2av[t4] lK/1
611 # a <1> rv2av[t2] lKRM*/1
612 # b <2> aassign[t5] KS
613 # c <1> leavesub[1 ref] K/REFC,1
615 # 1 <;> nextstate(main 546 (eval 15):1) v
618 # 4 <$> const(PV "other::backwards") s/BARE
620 # 6 <1> rv2av[t2] lK/1
624 # a <1> rv2av[t1] lKRM*/1
625 # b <2> aassign[t3] KS
626 # c <1> leavesub[1 ref] K/REFC,1
632 # chunk: # guarantee stability, regardless of algorithm
634 @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
638 checkOptree(note => q{},
640 code => q{use sort 'stable'; @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old; },
641 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
642 # 1 <;> nextstate(main 656 (eval 40):1) v
646 # 5 <1> rv2av[t9] lK/1
650 # 9 <1> rv2av[t2] lKRM*/1
651 # a <2> aassign[t14] KS
652 # b <1> leavesub[1 ref] K/REFC,1
654 # 1 <;> nextstate(main 578 (eval 15):1) v
658 # 5 <1> rv2av[t5] lK/1
662 # 9 <1> rv2av[t1] lKRM*/1
663 # a <2> aassign[t6] KS
664 # b <1> leavesub[1 ref] K/REFC,1
670 # chunk: # force use of mergesort (not portable outside Perl 5.8)
671 use sort '_mergesort';
672 @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
676 checkOptree(note => q{},
678 code => q{use sort '_mergesort'; @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old; },
679 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
680 # 1 <;> nextstate(main 662 (eval 42):1) v
684 # 5 <1> rv2av[t9] lK/1
688 # 9 <1> rv2av[t2] lKRM*/1
689 # a <2> aassign[t14] KS
690 # b <1> leavesub[1 ref] K/REFC,1
692 # 1 <;> nextstate(main 578 (eval 15):1) v
696 # 5 <1> rv2av[t5] lK/1
700 # 9 <1> rv2av[t1] lKRM*/1
701 # a <2> aassign[t6] KS
702 # b <1> leavesub[1 ref] K/REFC,1
708 # chunk: # you should have a good reason to do this!
709 @articles = sort {$FooPack::b <=> $FooPack::a} @files;
713 checkOptree(note => q{},
715 code => q{@articles = sort {$FooPack::b <=> $FooPack::a} @files; },
716 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
717 # 1 <;> nextstate(main 667 (eval 44):1) v
721 # 5 <1> rv2av[t7] lK/1
724 # 8 <#> gv[*articles] s
725 # 9 <1> rv2av[t2] lKRM*/1
726 # a <2> aassign[t8] KS
727 # b <1> leavesub[1 ref] K/REFC,1
729 # 1 <;> nextstate(main 546 (eval 15):1) v
733 # 5 <1> rv2av[t3] lK/1
736 # 8 <$> gv(*articles) s
737 # 9 <1> rv2av[t1] lKRM*/1
738 # a <2> aassign[t4] KS
739 # b <1> leavesub[1 ref] K/REFC,1
746 @result = sort { $a <=> $b } grep { $_ == $_ } @input;
750 checkOptree(note => q{},
752 code => q{@result = sort { $a <=> $b } grep { $_ == $_ } @input; },
753 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
754 # 1 <;> nextstate(main 673 (eval 46):1) v
759 # 6 <1> rv2av[t9] lKM/1
760 # 7 <@> grepstart lK*
761 # 8 <|> grepwhile(other->9)[t10] lK
769 # e <#> gv[*result] s
770 # f <1> rv2av[t2] lKRM*/1
771 # g <2> aassign[t5] KS/COMMON
772 # h <1> leavesub[1 ref] K/REFC,1
774 # 1 <;> nextstate(main 547 (eval 15):1) v
779 # 6 <1> rv2av[t3] lKM/1
780 # 7 <@> grepstart lK*
781 # 8 <|> grepwhile(other->9)[t4] lK
789 # e <$> gv(*result) s
790 # f <1> rv2av[t1] lKRM*/1
791 # g <2> aassign[t2] KS/COMMON
792 # h <1> leavesub[1 ref] K/REFC,1
798 # chunk: # void return context sort
799 sort { $a <=> $b } @input;
803 checkOptree(note => q{},
805 code => q{sort { $a <=> $b } @input; },
806 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
807 # 1 <;> nextstate(main 678 (eval 48):1) v
810 # 4 <1> rv2av[t5] lK/1
812 # 6 <1> leavesub[1 ref] K/REFC,1
814 # 1 <;> nextstate(main 546 (eval 15):1) v
817 # 4 <1> rv2av[t2] lK/1
819 # 6 <1> leavesub[1 ref] K/REFC,1
825 # chunk: # more void context, propagating ?
826 sort { $a <=> $b } grep { $_ == $_ } @input;
830 checkOptree(note => q{},
832 code => q{sort { $a <=> $b } grep { $_ == $_ } @input; },
833 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
834 # 1 <;> nextstate(main 684 (eval 50):1) v
838 # 5 <1> rv2av[t7] lKM/1
839 # 6 <@> grepstart lK*
840 # 7 <|> grepwhile(other->8)[t8] lK
847 # c <1> leavesub[1 ref] K/REFC,1
849 # 1 <;> nextstate(main 547 (eval 15):1) v
853 # 5 <1> rv2av[t2] lKM/1
854 # 6 <@> grepstart lK*
855 # 7 <|> grepwhile(other->8)[t3] lK
862 # c <1> leavesub[1 ref] K/REFC,1
868 # chunk: # scalar return context sort
869 $s = sort { $a <=> $b } @input;
873 checkOptree(note => q{},
875 code => q{$s = sort { $a <=> $b } @input; },
876 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
877 # 1 <;> nextstate(main 689 (eval 52):1) v
880 # 4 <1> rv2av[t6] lK/1
883 # 7 <2> sassign sKS/2
884 # 8 <1> leavesub[1 ref] K/REFC,1
886 # 1 <;> nextstate(main 546 (eval 15):1) v
889 # 4 <1> rv2av[t2] lK/1
892 # 7 <2> sassign sKS/2
893 # 8 <1> leavesub[1 ref] K/REFC,1
899 # chunk: $s = sort { $a <=> $b } grep { $_ == $_ } @input;
903 checkOptree(note => q{},
905 code => q{$s = sort { $a <=> $b } grep { $_ == $_ } @input; },
906 expect => <<'EOT_EOT', expect_nt => <<'EONT_EONT');
907 # 1 <;> nextstate(main 695 (eval 54):1) v
911 # 5 <1> rv2av[t8] lKM/1
912 # 6 <@> grepstart lK*
913 # 7 <|> grepwhile(other->8)[t9] lK
921 # d <2> sassign sKS/2
922 # e <1> leavesub[1 ref] K/REFC,1
924 # 1 <;> nextstate(main 547 (eval 15):1) v
928 # 5 <1> rv2av[t2] lKM/1
929 # 6 <@> grepstart lK*
930 # 7 <|> grepwhile(other->8)[t3] lK
938 # d <2> sassign sKS/2
939 # e <1> leavesub[1 ref] K/REFC,1