in reply to Sorting question

Maybe a dispatch table would help.

sub thing { my ( $ref, $sort_by ) = @_; my %sort_sub = ( thing1 => sub { $ref->{$a} <=> $ref->{$b} }, thing2 => sub { $ref->{$a}->[CON] <=> $ref->{$b}->[CON] }, etc => sub { 'and so forth' }, ); my $sorter = $sort_sub{$sort_by}; for my $key ( sort $sorter keys %{$ref} ) { # ... } }

Then you call it as thing( $ref, 'thing1' ), for example.

Replies are listed 'Best First'.
Re^2: Sorting question (sort ($$))
by lodin (Hermit) on Feb 13, 2008 at 00:53 UTC

    In this case it's unlikely to matter, but the sort subroutines are closures which means that they'll remember $ref and $a/$b will be package variables of the package in which the subroutines are defined. That means that if the subroutines are used in a sort in another package, the wrong $a/$b variables will be used. In order to solves that the ($$) prototype has special meaning. With that prototype $a and $b will be passed to the subroutine, and you use $_[0] and $_[1] instead:

    sub ($$) { $ref->{$_[0]} <=> $ref->{$_[1]} }
    An example:
    use strict; no warnings; # So many that they hide the output. { package Foo; sub doit { my ($sorter, @keys) = @_; return sort $sorter @keys; } } my @foo = (3, 1, 2); print '$a: ', join(' ', Foo::doit(sub { $a <=> $b }, @foo)), "\n"; print '@_: ', join(' ', Foo::doit(sub ($$) { $_[0] <=> $_[1] }, @foo)) +, "\n"; __END__ $a: 3 1 2 @_: 1 2 3
    This becomes useful (necessary) if the sort routines are abstracted further.

    Update: Fixed several typos.

    lodin