[H-GEN] perl question about sort()

Jason Parker-Burlingham jasonp at uq.net.au
Fri Feb 28 01:25:15 EST 2003


[ Humbug *General* list - semi-serious discussions about Humbug and     ]
[ Unix-related topics. Posts from non-subscribed addresses will vanish. ]

Tony Nugent <tony at linuxworks.com.au> writes:

> On Thu Feb 27 2003 at 10:28, Jason Parker-Burlingham wrote:
> > Tony Nugent <tony at linuxworks.com.au> writes:

> The use of map{} is new to me, and the talk about schwartzian
> transformation was a bit "heady".  But something did go click...

Good.  On both counts, I think; if I gave you more than you wanted to
know but answered your question too, I consider it a job well done!

> As an exercise for myself, I managed to write a little script that
> sorted the password file by UID in reverse order... it was more
> simple to do than I suspected.  Ok, so that's a start.

Excellent.

> I'm still a little hazy about the origin and importance of the $a
> and $b variables that "magically" appear.  For example:
> >       sort { $b->{age} <=> $a->{age} } @students
> Are the raw values that get compared always referred to as $a and
> $b?  Do they have global scope?

Yes, they have global scope.

I'm going out on a limb, but they're probably artifacts from when Perl
had only global variables and had no lexical scoping at all (lexical
scoping is what you're used to from languages like C, Java and Lisp; a
variable is visible only in the block in which it is declared).

I imagine some way was needed to pass values to the sort routine, and
instead of doing it like a standard sub:

        sub byage {
                my ($a, $b) = @_;
                $a->age <=> $b->age;
        }

they may have decided to nominate $a and $b to be universal sort
variables instead.

SO!  You should probably not use the global variables $a and $b in a
program, but it doesn't appear to generate a warning (and so it's
probably okay):

        $ perl -w -Mstrict -le'$a=4;print$a'
        4

Using the *lexical* variables $a and $b is completely okay.  The
reason for this (and don't read on unless you're interested and have a
strong stomach) is that Perl has **two** namespaces for variables.

There are "package" variables which are global (of course they belong
to the current package (by default), so you can still have more than
one $foo (such as $main::foo and $My::Example::foo)), and lexical
variables, explained above.  

The C<local> keyword can be used to hide the old value of a variable
inside some block (usually a sub) and to restore its old value when
the block is exited.

All of Perl's "special variables" like $_, $| and $@ (to name just a
few, see "perldoc perlvar" (another good manpage to take a look
through)) are package variables which is why you should C<local>ize
them if you're going to change them in a subroutine, because the
alternative is to change their value across the entire program from
that point on.

Phew!

> > Okay, you should also read the C<sort> section of the Perl manual (run
> > "perldoc -f sort") and the Perl FAQ entry on sorting
> > (run "perldoc -q sort").
> Now that is the most useful thing!  I wish I had known about this
> way before now!  Thanks.

perldoc contains the vast majority of what you'd otherwise find in
more than one book.  The FAQ especially is worth its weight in gold.
-- 
``I may have agreed to something involving a goat.''  -- CJ

--
* This is list (humbug) general handled by majordomo at lists.humbug.org.au .
* Postings to this list are only accepted from subscribed addresses of
* lists 'general' or 'general-post'.  See http://www.humbug.org.au/



More information about the General mailing list