Where does $ _ change in this perl code?

The following perl code generates a warning in PerlCritic (on activation):

sub natural_sort {
    my @sorted;
    @sorted = grep {s/(^|\D)0+(\d)/$1$2/g,1} sort grep {s/(\d+)/sprintf"%06.6d",$1/ge,1} @_;
}

Generated Warning:

Do not change $ _ in list functions

Learn more about this warning.

I don’t understand the warning because I don’t think I am changing $ _, although I suppose it should be. Can someone explain this to me please?

+3
source share
5 answers

Both of are grepchanging $_because you are using s//. For example, this:

grep {s/(^|\D)0+(\d)/$1$2/g,1}

matches this:

grep { $_ =~ s/(^|\D)0+(\d)/$1$2/g; 1 }

I think you are better off using it map, since you are not filtering anything with greps, you are simply using grepiterator:

sub natural_sort {
    my $t;
    return map { ($t = $_) =~ s/(^|\D)0+(\d)/$1$2/g; $t }
           sort
           map { ($t = $_) =~ s/(\d+)/sprintf"%06.6d",$1/ge; $t }
           @_;
}

. , List::MoreUtils, , map.

+10

(.. s///) grep, $_ , grepped.

+3

perldoc perlvar:

, Perl $_, :

  • :

abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, exp, glob, hex, int, lc, lcfirst, length, log, lstat, mkdir, oct, ord, pos, print, quotemeta, readlink, readpipe, ref, , ( ), rmdir, sin, split ( ), sqrt, stat, study, uc, ucfirst, unlink, unpack.

  • (-f, -d), -t, STDIN. . -X

  • m//, s/// tr///(aka y///), = ~.

  • foreach, .

  • grep() map().

  • ().

  • . , .

+3

, s $_, Perl 5.14.0 r s (.. s///r), . . perlbrew .

: Perl 5.14 ! Delta

, mu ( map), :

use 5.14.0;

sub natural_sort {
    return map { s/(^|\D)0+(\d)/$1$2/gr }
           sort
           map { s/(\d+)/sprintf"%06.6d",$1/gre }
           @_;
}
+2

, , ,

grep {s/(\d+)/sprintf"%06.6d",$1/ge,1} @_;

, , .

grep - , $_ @_. @_ , , , s/// , . :

sub test {grep {s/a/b/g; 1} @_}

my @array = qw(cat bat sat);

my @new = test @array;

say "@new";   # prints "cbt bbt sbt" as it should
say "@array"; # prints "cbt bbt sbt" as well, which is probably an error

, ( , $_ ), apply . List:: Gen ​​. apply :

sub apply (&@) {
    my ($sub, @ret) = @_;
    $sub->() for @ret;
    wantarray ? @ret : pop @ret
}

:

sub natural_sort {
    apply {s/(^|\D)0+(\d)/$1$2/g} sort apply {s/(\d+)/sprintf"%06.6d",$1/ge} @_
}

, , Perl, Schwartzian, .

+1

All Articles