Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things

Re^3: Pearls (not really) of Perl programming

by ysth (Canon)
on Nov 24, 2004 at 23:53 UTC ( #410284=note: print w/replies, xml ) Need Help??

in reply to Re^2: Pearls (not really) of Perl programming
in thread Pearls (not really) of Perl programming

This seems to rely on luck as the block may yield "" which sort is not advertised to accept.
That code always returns 1 or -1 AFAICT. Can you explain?

Update: it will return false if $a or $b isn't any of the types tested for, but false isn't "", it's both 0 and "":

$ perl -we'@_ = sort { "" } 1,2' Sort subroutine didn't return a numeric value at -e line 1. $ perl -we'@_ = sort { !1 } 1,2'

Replies are listed 'Best First'.
Re^4: Pearls (not really) of Perl programming
by rir (Vicar) on Nov 29, 2004 at 18:28 UTC
    Thanks for the correction. It was my error to be seduced by the control flow like use of logical short circuiting to the point of thinking statements instead of an expression. More succinctly: I had another braindead moment.

    Now that you've drawn my attention to the code again. I say it is that baroque. My initial justification was just for the  and 1 stuff which I still don't find so bad.

    I would still like a or $a cmp $b or a or 0 or  die "domain err". It is not readily apparent what is to happen with other/other comparisions. This seems like a significant decision point in the code (by the identifiers) and so a good place for extra clarity. I can imagine myself referring to this snippet to understand how all the subsequent parsing code is recieving data. This may be such a recurring problem in the codebase that it seems unimportant.

    What does irk is the inconsistent use of short-circuiting, the sub-clauses are unnecessary and so confusing. (I just trusted that aspect the first time around.

    If I were going to write in that form I'd write something like:

    @List = sort { $a eq "one" and -1 or $b eq "one" and 1 or $a eq "two" and -1 or $b eq "two" and 1 # no need to check if $a eq one or $a eq "thr" and -1 or $b eq "thr" and 1 or 0 # advertising the default case }
    Be well.
Re^4: Pearls (not really) of Perl programming
by Courage (Parson) on Dec 01, 2004 at 15:21 UTC
    Although you give examples of strange code and it does not pretend to be good, I can't resist pointing that:

    code block given to sort must behave (as POD stays.)
    Namely, once f(a,b) return false f(b,a) must return true.
    Some versions of perl dumped core when fed some misbehaving comparision sub.
    Such core dumps were fixed, but general rule remain: comparision sub must behave

    This means that sort {rand(5) <=> rand(5)} is obviously wrong, but sort {1} also not good.

    Best regards,
    Courage, the Cowardly Dog

      The comparison function for sort must not just return 'true' and 'false'.
      It must return '-1', '0' and '+1' for comparing 'Less Than', 'Equal To' and 'Greater Than', just like the two standard comparison operators 'cmp' and '<=>' (for stringwise and numeric comparison respectively).

      Just using 'true' (ie non-zero, probably 1) and false (ie 0 or '') will lead to confusion.

      If f(a, b) is 'false' then f(b, a) must also be false because a 'Equals' b - for whatever value of 'Equals' this sorting choses to use.
      If f(a, b) is 'true' then f(b, a) must return '-1' (ie a true value, but *not* just true) because a is 'Greater Than' b in this case, and therefore b must be 'Less Than' a - not 'Equal To', or something is decidedly wierd.

      You have to be consistent however you chose to do it.

        You're right, thanks for correction.

        I just could not resist to point out for general idea (I saw that in p5p list) but I forgot to recheck all details

        But once we decided to be precise, let me make additional correction.
        Requirement to return '-1', '0' and '+1' is too restrictive. According to perldoc -f sort:

        parison order. If SUBNAME is specified, it gives the name of a subroutine that returns an integer less than, equal to, or greater than 0, depending on how the elements of the list are to be ordered. (The "<=>" and "cmp" operators are extremely useful in such routines.) SUBNAME may be a scalar variable
        So any negative and positive values are ok.

        Best regards,
        Courage, the Cowardly Dog

      To clarify, prior to perl 5.005 (!) sort used to use libc's qsort, which would sometimes coredump on certain platforms with pathological return values. But this isn't a concern any longer unless you are stuck with a really old perl.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://410284]
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (2)
As of 2018-03-21 03:30 GMT
Find Nodes?
    Voting Booth?
    When I think of a mole I think of:

    Results (263 votes). Check out past polls.