in reply to Re: package globals and sort()
in thread package globals and sort()

Ah. Sorry. The method doesn't actually do the sort (too much copying for my tastes). It just defines the sort rules. Something like:
package MyOrder; use strict; # export junk goes here... my %order = ( # order hash goes here... ); sub SortMyWay { if ( exists $order{$a} and exists $order{$b} ) { return $order{$a} <=> $order{$b} } elsif ( exists $order{$a} ) { return 1 } elsif ( exists $order{$b} ) { return -1 } else { return $a cmp $b } } package main; use strict; # use the module with the sort stuff in it, # which also exports sub SortMyWay my @foo = ( # stuff to sort goes here... ); my @bar = sort SortMyWay @foo;
and of course I get an error. sigh. I wonder if AUTOLOAD could do it. I never used that before...

Replies are listed 'Best First'.
Re: Re: Re: package globals and sort()
by tachyon (Chancellor) on Apr 19, 2002 at 01:10 UTC

    Just do the actual sort in the MyOrder Package as shown. Note as we pass list references we pass 4 bytes in and 4 bytes out of the MyOrder package.

    package MyOrder; my %order = ( ); sub SortCriteria { if ( exists $order{$a} and exists $order{$b} ) { return $order{$a} <=> $order{$b} } elsif ( exists $order{$a} ) { return 1 } elsif ( exists $order{$b} ) { return -1 } else { return $a cmp $b } } sub SortMyWay { my $list_ref = shift; return [sort SortCriteria @$list_ref]; } package main; use strict; my @foo = qw( j a p h , ); my $bar = MyOrder::SortMyWay(\@foo); my @bar = @$bar; print "@bar";

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Won't the @$list_ref cause an array copy? Not to mention the sort itself, and then again on the return. Forgive me, I was never all that clear where perl copies vs refs. Since the list is between 10,000 entries and 1,000,000 entries, I don't want to copy it any more then required.

        No there is no copy. If you know about C you will know about *pointers*. Anyway even if you don't all that is passed is a pointer to the original array. @$list_ref just uses the array pointed to by $list_ref. No copy is made. This is why it is efficient to pass array refs to and from subs as you never copy an array you don't have to.

        The is a way to implement things the way you wanted originally by passing $a and $b to the other package but this is far less efficient so don't do it! Here it is just to show you it can be done. We can even localise $a and $b :-)

        package MyOrder; use strict; my %order = (); sub SortMyWay { my ($a,$b) = @_; if ( exists $order{$a} and exists $order{$b} ) { return $order{$a} <=> $order{$b} } elsif ( exists $order{$a} ) { return 1 } elsif ( exists $order{$b} ) { return -1 } else { return $a cmp $b } } package main; use strict; my @foo = qw( j a p h , ); my @bar = sort { MyOrder::SortMyWay($a,$b) } @foo; print "@bar";

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print