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::MoreUtils::apply().


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)

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

 list_funcs = map grep List::Util::first

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

 add_list_funcs = Foo::Bar::listmunge


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

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

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

and not like this:

  use List::MoreUtils 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.


Chris Dolan <cdolan@cpan.org>

Michael Wolf <MichaelRWolf@att.net>


Copyright (C) 2006 Chris Dolan. All rights reserved.

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