3

Here's my entire script, crafted to include two variable with the same name, one of which is masking the other:

#!/usr/bin/env perl
use strict;
use warnings;

my $hi = "First hi";
print "$hi\n";

{
    my $hi = "Second hi";
    print "$hi\n";
}

print "$hi\n";

If I run this script, I get this output, and noticeably no warnings:

First hi
Second hi
First hi

If I remove the curly braces around the second $hi variable so that is in the same scope as the first $hi variable, I get this warning:

"my" variable $hi masks earlier declaration in same scope at hi.pl

However, I want this warning even when the variable is not in the same scope. I want the warning every time a variable name is shadowing another. How can I enable this warning? Is there a Perl Critic policy that I can enable that will warn me about this?

toolic
  • 57,801
  • 17
  • 75
  • 117
Flimm
  • 136,138
  • 45
  • 251
  • 267
  • 1
    This is a feature of "my" variables, they live on their own scope – Miguel Prz Aug 14 '14 at 09:28
  • @MiguelPrz: I love that "my" variables live in their own scope, I don't love that Perl fails to warn me about variable shadowing in this case. – Flimm Aug 14 '14 at 09:30

2 Answers2

2

Did you try this:

Perl::Critic::Policy::Variables::ProhibitReusedNames;

Miller
  • 34,962
  • 4
  • 39
  • 60
fugu
  • 6,417
  • 5
  • 40
  • 75
1

The probable reason is:

my $a = 1;
# ...
{
   my $a = 2;
   # ...
}
# ...

may make sense, while

my $a = 1;
# ...
my $a = 2;
# ...

does not.

You might file an enhancement request to get warnings about the first case, too (as gcc does for C).

U. Windl
  • 3,480
  • 26
  • 54
  • In both examples, the second declaration of `$a` makes the first `$a` inaccessible, at least while in scope. This means the variable declaration is masking an earlier declaration, and so I would expect the warning to be emitted. Why isn't it? Is there a way to enable it? – Flimm Aug 28 '23 at 14:03
  • @Flimm because being able to reuse a name in an inner scope without causing problems is the entire reason for lexical scoping to exist :) – hobbs Aug 28 '23 at 14:15
  • 1
    I'm not sure it is. I think you can use scope like this: `{ my $a = 1; } { my $a = 2; } { my $a = 3 }` . Here we have scope without variable shadowing. The brackets prevent the variable from being used outside of the scope, which is very useful. Variable shadowing is dangerous because you might be referring to a variable which you don't intend to refer to, hence why a warning would be useful. – Flimm Aug 28 '23 at 16:01