---
name: "Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions"
section: "3pm"
platform: "linux"
package: "perl-perl-critic"
version: "1.156-3"
release: "Arch Linux 2026-11-01"
platforms: ["linux"]
url: "https://new.carta.tech/Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions"
---

# Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions(3pm)

Don't modify "$\_" in list functions.

## NAME

Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions - Don't modify "$\_" in list functions.

## AFFILIATION

This Policy is part of the core Perl::Critic distribution.

## DESCRIPTION

`"map"`, `"grep"` and other list operators are intended to transform arrays into other arrays by applying code to the array elements one by one.  For speed, the elements are referenced via a `$_` alias rather than copying them.  As a consequence, if the code block of the `"map"` or `"grep"` modify `$_` in any way, then it is actually modifying the source array.  This IS technically allowed, but those side effects can be quite surprising, especially when the array being passed is `@_` or perhaps `values(%ENV)`!  Instead authors should restrict in-place array modification to `"for(@array) { ... }"` constructs instead, or use `List::SomeUtils:apply()` or `List::MoreUtils::apply()`.

## CONFIGURATION

By default, this policy applies to the following list functions:

```
    map grep
    List::Util qw(first)
    List::MoreUtils qw(any all none notall true false firstidx
                       first_index lastidx last_index insert_after
                       insert_after_string)
    List::SomeUtils qw(any all none notall true false firstidx
                       first_index lastidx last_index insert_after
                       insert_after_string)
```

This list can be overridden the *.perlcriticrc* file like this:

```
    [ControlStructures::ProhibitMutatingListFunctions]
    list_funcs = map grep List::Util::first
```

Or, one can just append to the list like so:

```
    [ControlStructures::ProhibitMutatingListFunctions]
    add_list_funcs = Foo::Bar::listmunge
```

## LIMITATIONS

This policy deliberately does not apply to `"for (@array) { ... }"` or `List::MoreUtils::apply()` `List::SomeUtils::apply()`.

Currently, the policy only detects explicit external module usage like this:

```
    my @out = List::MoreUtils::any {s/^foo//} @in;
    my @out = List::SomeUtils::any {s/^foo//} @in;
```

and not like this:

```
    use List::MoreUtils qw(any);
    my @out = any {s/^foo//} @in;
    use List::SomeUtils qw(any);
    my @out = any {s/^foo//} @in;
```

This policy looks only for modifications of `$_`.  Other naughtiness could include modifying `$a` and `$b` in `"sort"` and the like. That's beyond the scope of this policy.

## SEE ALSO

There is discussion of this policy at \<http://perlmonks.org/index.pl?node\_id=743445\>.

## AUTHOR

Chris Dolan \<cdolan@cpan.org\>

Michael Wolf \<MichaelRWolf@att.net\>

## COPYRIGHT

Copyright (c) 2006-2021 Chris Dolan.

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
