This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Merge gv_AVadd(), gv_HVadd() and gv_SVadd() into gv_add_by_type().
[perl5.git] / lib / sort.pm
index e785003..922f82b 100644 (file)
@@ -1,13 +1,9 @@
 package sort;
 
-our $VERSION = '1.02';
+our $VERSION = '2.01';
 
-# Currently the hints for pp_sort are stored in the global variable
-# $sort::hints. An improvement would be to store them in $^H{SORT} and have
-# this information available somewhere in the listop OP_SORT, to allow lexical
-# scoping of this pragma. -- rgs 2002-04-30
-
-our $hints            = 0;
+# The hints for pp_sort are now stored in $^H{sort}; older versions
+# of perl used the global variable $sort::hints. -- rjh 2005-12-19
 
 $sort::quicksort_bit   = 0x00000001;
 $sort::mergesort_bit   = 0x00000002;
@@ -23,18 +19,18 @@ sub import {
        Carp::croak("sort pragma requires arguments");
     }
     local $_;
-    no warnings 'uninitialized';       # bitops would warn
+    $^H{sort} //= 0;
     while ($_ = shift(@_)) {
        if (/^_q(?:uick)?sort$/) {
-           $hints &= ~$sort::sort_bits;
-           $hints |=  $sort::quicksort_bit;
+           $^H{sort} &= ~$sort::sort_bits;
+           $^H{sort} |=  $sort::quicksort_bit;
        } elsif ($_ eq '_mergesort') {
-           $hints &= ~$sort::sort_bits;
-           $hints |=  $sort::mergesort_bit;
+           $^H{sort} &= ~$sort::sort_bits;
+           $^H{sort} |=  $sort::mergesort_bit;
        } elsif ($_ eq 'stable') {
-           $hints |=  $sort::stable_bit;
+           $^H{sort} |=  $sort::stable_bit;
        } elsif ($_ eq 'defaults') {
-           $hints =   0;
+           $^H{sort} =   0;
        } else {
            require Carp;
            Carp::croak("sort: unknown subpragma '$_'");
@@ -52,11 +48,11 @@ sub unimport {
     no warnings 'uninitialized';       # bitops would warn
     while ($_ = shift(@_)) {
        if (/^_q(?:uick)?sort$/) {
-           $hints &= ~$sort::sort_bits;
+           $^H{sort} &= ~$sort::sort_bits;
        } elsif ($_ eq '_mergesort') {
-           $hints &= ~$sort::sort_bits;
+           $^H{sort} &= ~$sort::sort_bits;
        } elsif ($_ eq 'stable') {
-           $hints &= ~$sort::stable_bit;
+           $^H{sort} &= ~$sort::stable_bit;
        } else {
            require Carp;
            Carp::croak("sort: unknown subpragma '$_'");
@@ -66,10 +62,10 @@ sub unimport {
 
 sub current {
     my @sort;
-    if ($hints) {
-       push @sort, 'quicksort' if $hints & $sort::quicksort_bit;
-       push @sort, 'mergesort' if $hints & $sort::mergesort_bit;
-       push @sort, 'stable'    if $hints & $sort::stable_bit;
+    if ($^H{sort}) {
+       push @sort, 'quicksort' if $^H{sort} & $sort::quicksort_bit;
+       push @sort, 'mergesort' if $^H{sort} & $sort::mergesort_bit;
+       push @sort, 'stable'    if $^H{sort} & $sort::stable_bit;
     }
     push @sort, 'mergesort' unless @sort;
     join(' ', @sort);
@@ -92,7 +88,10 @@ sort - perl pragma to control sort() behaviour
 
     use sort '_qsort';         # alias for quicksort
 
-    my $current = sort::current();     # identify prevailing algorithm
+    my $current;
+    BEGIN {
+       $current = sort::current();     # identify prevailing algorithm
+    }
 
 =head1 DESCRIPTION
 
@@ -152,50 +151,46 @@ have exactly the same effect, leaving the choice of sort algorithm open.
 
 =head1 CAVEATS
 
-This pragma is not lexically scoped: its effect is global to the program
-it appears in.  That means the following will probably not do what you
-expect, because I<both> pragmas take effect at compile time, before
-I<either> C<sort()> happens.
+As of Perl 5.10, this pragma is lexically scoped and takes effect
+at compile time. In earlier versions its effect was global and took
+effect at run-time; the documentation suggested using C<eval()> to
+change the behaviour:
 
-  { use sort "_quicksort";
+  { eval 'use sort qw(defaults _quicksort)'; # force quicksort
+    eval 'no sort "stable"';      # stability not wanted
     print sort::current . "\n";
     @a = sort @b;
+    eval 'use sort "defaults"';   # clean up, for others
   }
-  { use sort "stable";
+  { eval 'use sort qw(defaults stable)';     # force stability
     print sort::current . "\n";
     @c = sort @d;
+    eval 'use sort "defaults"';   # clean up, for others
   }
-  # prints:
-  # quicksort stable
-  # quicksort stable
-
-You can achieve the effect you probably wanted by using C<eval()>
-to defer the pragmas until run time.  Use the quoted argument
-form of C<eval()>, I<not> the BLOCK form, as in
 
-  eval { use sort "_quicksort" }; # WRONG
+Such code no longer has the desired effect, for two reasons.
+Firstly, the use of C<eval()> means that the sorting algorithm
+is not changed until runtime, by which time it's too late to
+have any effect. Secondly, C<sort::current> is also called at
+run-time, when in fact the compile-time value of C<sort::current>
+is the one that matters.
 
-or the effect will still be at compile time.
-Reset to default options before selecting other subpragmas
-(in case somebody carelessly left them on) and after sorting,
-as a courtesy to others.
+So now this code would be written:
 
-  { eval 'use sort qw(defaults _quicksort)'; # force quicksort
-    eval 'no sort "stable"';      # stability not wanted
-    print sort::current . "\n";
+  { use sort qw(defaults _quicksort); # force quicksort
+    no sort "stable";      # stability not wanted
+    my $current;
+    BEGIN { $current = print sort::current; }
+    print "$current\n";
     @a = sort @b;
-    eval 'use sort "defaults"';   # clean up, for others
+    # Pragmas go out of scope at the end of the block
   }
-  { eval 'use sort qw(defaults stable)';     # force stability
-    print sort::current . "\n";
+  { use sort qw(defaults stable);     # force stability
+    my $current;
+    BEGIN { $current = print sort::current; }
+    print "$current\n";
     @c = sort @d;
-    eval 'use sort "defaults"';   # clean up, for others
   }
-  # prints:
-  # quicksort
-  # stable
-
-Scoping for this pragma may change in future versions.
 
 =cut