in reply to sort routines crossing package lines

This is because $a and $b are really $main::a and $main::b. You can solve this in two other ways:

  1. Use prototypes on your sort subs so instead you would have  sub caseless ($$) { lc($_[0]) cmp lc($_[1]) }
  2. Or use the full name of $a and $b like this  sub caseless { lc($main::a) cmp lc($main::b) }

Frank Wiles <frank@wiles.org>
http://www.wiles.org

Replies are listed 'Best First'.
Re^2: sort routines crossing package lines
by DrWhy (Chaplain) on Nov 24, 2004 at 21:36 UTC
    Use prototypes on your sort subs so instead you would have sub caseless ($$) { lc($_[0]) cmp lc($_[1]) }

    Yes, but I don't want to. perldoc -f sort claims that this introduces a performance hit and the application is already slow enough. I'm sorting lists with thousands of elements.

    Or use the full name of $a and $b like this sub caseless { lc($main::a) cmp lc($main::b) }
    That is only true if all uses of the sort routine are in package main. In this application this is not the case. This routine has to work when called from a number of different packages.

    BTW, I'm not necessarily looking for an alternate implementation. What I'm looking for is understanding the reason why exporting $a and $b does not make this work, but exporting their typeglobs does.

    --DrWhy

    "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."

      I've heard that prototypes slow down subroutines, however in practice I've found that it doesn't usually effect an application. I would suggest trying it to see.

      I believe the reason is they aren't just package variables, but "special package variables" according to man perlvar.

      Frank Wiles <frank@wiles.org>
      http://www.wiles.org

      According to other monks' messages, below, you can sort short lists in microseconds or nanoseconds. So even though your lists have thousands of elements, I doubt that sorting is the cause of your speed concerns.

      Profile your program.

      I bet you'll find huge whacks of time spent copying arrays in a function call in an inner loop, where you should be passing a reference, or some other efficiency error. Or it might be your algorithmn that needs some re-thinking. Are you processing things in an item-by-item loop, when you could leave Perl to process the whole set at once?

      --
      TTTATCGGTCGTTATATAGATGTTTGCA

        This is a good point. I actually believe the big time hog is the large number of separate (and in some cases rather complex) queries made on the backend database. There may be some issues with passing/assigning arrays/hashes, but I've quashed alot of things like that already with no humanly noticeable improvement in speed.

        As for the impact of prototyped vs unprototyped sort routines I timed a portion of the code that does a lot of sorting with each version. The prototyped version added about a hundredth of a second to execution time (1.371 vs 1.382 seconds). So I've gone with the more straightforward prototyped implementation, ignoring the minute slowdown.

        --DrWhy

        "If God had meant for us to think for ourselves he would have given us brains. Oh, wait..."