Search code examples
perlenvironment-variablesperl-critic

Perlcritic: How can I resolve '^Magic variable "$ENV" should be assigned as "local"'?


I am writing a perl script that needs to set a number of environment variables before calling an external program. My code has the form

$ENV{'VAR1'}    = "value1";
$ENV{'VAR2'}    = "value2";

When running this through perlcritic, I get a severity 4 violation for every such assignement:

^Magic variable "$ENV" should be assigned as "local"

Googling that error message didn't give me any good solutions. The perlcritic violation that complains in that case is Variables::RequireLocalizedPunctuationVars, and the example given deals with localizing a file handle. I tried to find the relevant section in Perl Best Practices, but it only talks about localizing package variables.

One solution I tried is to localize %ENV using the following statement before the assignments.

local %ENV = ();

This doesn't resolve the violation.

My question is the following:

Is that Perlcritic violation even relevant for assignments to %ENV, or can I ignore it?

If it's relevant, what's the best way to resolve it?


Solution

  • Perlcritic warnings are not The Word of God. They are simply warnings about situations that, if managed incorrectly, could get you into trouble.

    Is that Perlcritic violation even relevant for assignments to %ENV, or can I ignore it?

    This warning tells you that:

    1. Global Variables have the very real possibility of action at a distance.
    2. This possibility is even more dangerous when dealing with those variables that change the operation of built in functions.

    Is that relevant for %ENV? If you spawn more than one child process in your program, Yes. If someone changes your program later to spawn another child, Yes.

    If it's relevant, what's the best way to resolve it?

    Now here is where being the human being becomes important. You need to make a value judgement.

    Possible actions:

    • Ignore the warning and hope that future maintainers aren't bitten by your usage of this Global Variable.
    • Change your code to avoid the situation you are being warned about. The syntax suggested by choroba is a fine option.

    Now if you have made a change, are still getting the warning, and believe that the warning is now in error, you can do one or more of:

    • Be a good citizen and Submit a bug report.
    • use the comment ## no critic (RequireLocalizedPunctuationVars) on the affected lines or on it's own line before the lines in question.
    • Or more excessively disable the rule or just create an exception for %ENV in your .perlcriticrc file.