Disclaimer: I have not looked into the Perl internals of sorting, so this is based just on my naive observations.

The method of using $test = $a || shift is an interesting way to implement a dual-use function, but you get bitten by Perl magic as you see.

In the first case, Perl rightfully complains about the variables $a and $b only being used once, since that is what you effectively do.

In the second case, deep Perl (optimization) magic is at work, since the variables $a and $b get filled with sort parameters for speed reasons and thus get "used" as far as Perl (or rather, the warnings-part of perl) is concerned. So, for sorting, $a and $b have been declared globally by the sort magic, and then warnings finds them already used (and maybe even declared) and thus shuts up.

I don't see any good solution to your dilemma, as the two or three approaches I see only lead down to beaten but bad paths :

#!/usr/bin/perl -w use strict; my ($a, $b); # Bad bad bad thing ! ($a, $b) = ( "5","6" ); sub mySort { return ($a||shift) cmp ($b||shift); }; print "\n1: ", mySort( "1","2" ); print "\n2: ", join " ", sort qw!d b c a!; print "\n3: ", mySort( "8","7" ), "\n"; print "\n\$a: $a, \$b : $b\n";
This code prints, when run
G:\>perl -w test.pl 1: -1 2: a b c d 3: -1 $a: 5, $b : 6
Here, the cases 1 and 2 are pretty sane, and as you see, even the my-declared variables $a and $b didn't get clobbered. But (and there's always a "but") case 3 is a very nice case of how to hide errors in interesting and nonobvious ways. If not called explicitly via sort, the routine now accesses the my-declared variables $a and $b, which have been initialized (by a stupid user understanding none of the code) to (5,6), which messes up all subsequent compares. So this is a really bad idea, because you can't make sure that noone initializes your "protectively" predeclared variables...

I'm not sure that there is no perlish idiom for handling such cases, but I haven't seen them yet :-)


In reply to Re: Sort and related stuff by Corion
in thread Sort and related stuff by leons

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.