tombmbdil has asked for the wisdom of the Perl Monks concerning the following question:

In one of my scripts I currently have a section similar to the following so that I can sort strings numerically, rather than alphabetically:
# sample data my %network = ( 10.1.0.1, { 'name' => 'vlan 2' } 10.2.0.2, { 'name' => 'vlan 3' } ); foreach my $network (sort { by_num($networks{$a}->{'name'}) <=> by_num +($networks{$b}->{'name'}) or $a cmp $b } keys %networks ) { # do stuff... } # Extract the number from a string # Used to sort Network names by vlan number, rather than alphabeticall +y sub by_num { my $key = shift; $key =~ /(\d+)/; return $1; }
I would like to add something to the top of the script to make sorting alphabetically or numerically an option, and I was hoping to consult the monks for an elegant solution. I thought maybe I could use anonymous subroutines...
#### untested/concept code below # set the following to either 'alpha' or 'num' $sortby= 'alpha'; my %sort_network; $sort_network{'alpha'} = sub { $a->{'name'} cmp $b->{'name'} }; $sort_network{'num'} = sub { by_num($a->{'name'}) <=> by_num($b->{'nam +e'} ) or $a->{'name'} cmp $b->{'name'}; foreach my $network (sort &$sort_network{$sortby} keys %networks ) { # do stuff... }
I think this should work, but I was wondering if there might be a more obvious/elegant solution.

Replies are listed 'Best First'.
Re: Variable Subroutine
by broquaint (Abbot) on May 27, 2003 at 17:09 UTC
    Modify your subs so the subname can be passed as an argument to sort e.g
    sub by_num { my($x,$y) = ($a =~ /(\d+)/, $b =~ /(\d+)/); return $x <=> $y; } sub by_abc { return $a cmp $b; } my $f = 'by_num'; my @args = qw/ foo1 bar2 baz3 /; print "$f - ", sort($f @args), $/; $f = 'by_abc'; print "$f - ", sort($f @args), $/; __output__ by_num - foo1bar2baz3 by_abc - bar2baz3foo1
    But your solution is fine as it stands (although you need to call the function in the sort block e.g sort { &$sort_network{$sortby} } keys %networks).
    HTH

    _________
    broquaint

      Aha! That's much better. I remember reading about that sort feature, but it didn't really sink in. Thanks.
Re: Variable Subroutine
by Coplan (Pilgrim) on May 27, 2003 at 17:27 UTC
    Your concept should work, at least it's one possible solution. I would personally make a sort subroutine, and just pass commands to it.

    #!/usr/bin/perl # UNTESTED CODE use strict; $sortby = 'alpha'; # or num my $network = sort($sortby); sub sort { my $method = shift; my $sorted; $method = 'alpha' if ($method eq ''); # Default if ($method eq 'alpha') { $sorted = # alpha sort method } elsif ($method eq 'num') { $sorted = # num sort method } else { $sorted = "Error: No sort method defined!\n"; } return $sorted; }

    I'm just curious to know if you've considered command line options? Rather than require the end user to manually edit the file every time, it would be worthwhile to utilize some sort of run-time configuration. Of course, you would always want to have some sort of default.

    --Coplan