In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/1f74a12bfce8b82144fa7fef29618af1e8023298?hp=21921336d307f4b7bf907befab709a9d086d2d7a>
- Log ----------------------------------------------------------------- commit 1f74a12bfce8b82144fa7fef29618af1e8023298 Author: Christian Millour <cm.p...@abtela.com> Date: Thu Jan 19 11:49:03 2017 +0100 document nature and use of $a and $b in sort() Signed-off-by: Abigail <abig...@abigail.be> ----------------------------------------------------------------------- Summary of changes: pod/perlfunc.pod | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) mode change 100644 => 100755 pod/perlfunc.pod diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod old mode 100644 new mode 100755 index d4dc2dfd53..6294b5d65f --- a/pod/perlfunc.pod +++ b/pod/perlfunc.pod @@ -7167,9 +7167,7 @@ If the subroutine's prototype is C<($$)>, the elements to be compared are passed by reference in L<C<@_>|perlvar/@_>, as for a normal subroutine. This is slower than unprototyped subroutines, where the elements to be compared are passed into the subroutine as the package global variables -C<$a> and C<$b> (see example below). Note that in the latter case, it -is usually highly counter-productive to declare C<$a> and C<$b> as -lexicals. +C<$a> and C<$b> (see example below). If the subroutine is an XSUB, the elements to be compared are pushed on to the stack, the way arguments are usually passed to XSUBs. C<$a> and @@ -7314,16 +7312,48 @@ C<find_records()> then you can use: my @contact = sort(find_records @key); my @contact = sort(find_records (@key)); -You I<must not> declare C<$a> -and C<$b> as lexicals. They are package globals. That means -that if you're in the C<main> package and type +C<$a> and C<$b> are set as package globals in the package the sort() is +called from. That means C<$main::a> and C<$main::b> (or C<$::a> and +C<$::b>) in the C<main> package, C<$FooPack::a> and C<$FooPack::b> in the +C<FooPack> package, etc. If the sort block is in scope of a C<my> or +C<state> declaration of C<$a> and/or C<$b>, you I<must> spell out the full +name of the variables in the sort block : - my @articles = sort {$b <=> $a} @files; + package main; + my $a = "C"; # DANGER, Will Robinson, DANGER !!! + + print sort { $a cmp $b } qw(A C E G B D F H); # WRONG + sub badlexi { $a cmp $b } + print sort badlexi qw(A C E G B D F H); # WRONG + # the above print BACFEDGH or some other incorrect ordering + + print sort { $::a cmp $::b } qw(A C E G B D F H); # OK + print sort { our $a cmp our $b } qw(A C E G B D F H); # also OK + print sort { our ($a, $b); $a cmp $b } qw(A C E G B D F H); # also OK + sub lexi { our $a cmp our $b } + print sort lexi qw(A C E G B D F H); # also OK + # the above print ABCDEFGH + +With proper care you may mix package and my (or state) C<$a> and/or C<$b>: + + my $a = { tiny => -2, small => -1, normal => 0, big => 1, huge => 2 }; + say sort { $a->{our $a} <=> $a->{our $b} } qw{ huge normal tiny small big}; + # prints tinysmallnormalbighuge + +C<$a> and C<$b> are implicitely local to the sort() execution and regain their +former values upon completing the sort. + +Sort subroutines written using C<$a> and C<$b> are bound to their calling +package. It is possible, but of limited interest, to define them in a +different package, since the subroutine must still refer to the calling +package's C<$a> and C<$b> : -then C<$a> and C<$b> are C<$main::a> and C<$main::b> (or C<$::a> and C<$::b>), -but if you're in the C<FooPack> package, it's the same as typing + package Foo; + sub lexi { $Bar::a cmp $Bar::b } + package Bar; + ... sort Foo::lexi ... - my @articles = sort {$FooPack::b <=> $FooPack::a} @files; +Use the prototyped versions (see above) for a more generic alternative. The comparison function is required to behave. If it returns inconsistent results (sometimes saying C<$x[1]> is less than C<$x[2]> and -- Perl5 Master Repository