Subject: | RequireInitializationForLocalVars on $@ and $! |
Date: | Wed, 28 Oct 2009 12:00:22 +1100 |
To: | bug-Perl-Critic [...] rt.cpan.org |
From: | Kevin Ryde <user42 [...] zip.com.au> |
In the current perlcritic cvs RequireInitializationForLocalVars reports
a violation on
local $@;
or
local $!;
where I hoped it might recognise them as output variables not normally
given an initializer when localizing. (Localizing to avoid clobbering a
caller's value, etc.)
A bit of a grep suggests "local $@;" is quite common. $! less so but
has the same rationale. Perhaps like below,
Index: lib/Perl/Critic/Policy/Variables/RequireInitializationForLocalVars.pm
===================================================================
--- lib/Perl/Critic/Policy/Variables/RequireInitializationForLocalVars.pm (revision 3692)
+++ lib/Perl/Critic/Policy/Variables/RequireInitializationForLocalVars.pm (working copy)
@@ -33,6 +33,9 @@
sub violates {
my ( $self, $elem, undef ) = @_;
+
+ return if List::MoreUtils::all {_is_output_var($_)} $elem->variables;
+
if ( $elem->type() eq 'local' && !_is_initialized($elem) ) {
return $self->violation( $DESC, $EXPL, $elem );
}
@@ -41,6 +44,15 @@
#-----------------------------------------------------------------------------
+# variables which are outputs of various things and therefore normally won't
+# have initializers in a "local"
+my %output_vars = ('$!' => 1,
+ '$@' => 1);
+sub _is_output_var {
+ my ($str) = @_;
+ return $output_vars{$str};
+}
+
sub _is_initialized {
my $elem = shift;
my $wanted = sub { $_[1]->isa('PPI::Token::Operator') && $_[1] eq q{=} };
@@ -88,7 +100,15 @@
}
+=head2 Allowed Forms
+An initializer is not required for C<$@> and C<$!> since they're normally
+outputs from a block of code or a function.
+
+ local $@; # ok
+ eval { ... }
+
+
=head1 CONFIGURATION
This Policy is not configurable except for the standard options.
Index: t/Variables/RequireInitializationForLocalVars.run
===================================================================
--- t/Variables/RequireInitializationForLocalVars.run (revision 3692)
+++ t/Variables/RequireInitializationForLocalVars.run (working copy)
@@ -26,8 +26,22 @@
our $bar
our ($foo, $bar);
+local $!;
+local $@;
+local ($!, $@);
+
#-----------------------------------------------------------------------------
+## name mixture of $! and other var
+## failures 2
+## cut
+
+local ($!, $foo);
+local ($var, $@);
+
+
+#-----------------------------------------------------------------------------
+
## name key named "local"
## failures 0
## cut