Perl::...ctions(3pm)

πŸ’– NAME πŸ’–

okay so bestie, welcome to the User Contributed Perl Documentation page for Perl::...ctions(3pm) β€” the full policy name is Perl::Critic::Policy::ControlStructures::ProhibitMutatingListFunctions, and it's literally: Don't modify $_ in list functions. πŸ’…

🌸 AFFILIATION 🌸

This Policy is part of the core Perl::Critic distribution. periodt. πŸ‘‘

✨ DESCRIPTION ✨

So 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 in 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(). noted. πŸ’…

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>. iykyk πŸ‘€

πŸ‘‘ AUTHOR πŸ‘‘

Chris Dolan <cdolan@cpan.org>

Michael Wolf <MichaelRWolf@att.net>

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.


signed off from perl v5.42.0, dated 2024-10-23, with Perl::...ctions(3pm) energy β€” mwah πŸ’–πŸŽ€βœ¨

πŸ“¦ where this page comes from