Skip Menu |

Preferred bug tracker

Please visit the preferred bug tracker to report your issue.

This queue is for tickets about the Perl-Critic CPAN distribution.

Report information
The Basics
Id: 38289
Status: open
Priority: 0/
Queue: Perl-Critic

People
Owner: Nobody in particular
Requestors: EDAVIS [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: Suggested policy: capture variable passed in subroutine call
Perl's builtin capture variables like $1 have strange behaviour. They are globals, yet saved and restored for subroutine entry in a special way that differs from ordinary localization. This means it is unwise to pass $1 as an argument to a subroutine, unless you are 100% sure the subroutine's author followed the policy 'always unpack @_ first'. Any regexp operation in the subroutine will change its arguments. For example, #!/usr/bin/perl use warnings; use strict; use 5.010; my $options = 'hello'; sub f { say 'hello' if $options =~ /hello/xm; my @args = @_; say "args are @args"; } $_ = 'foo'; if (/(\w+)/xm) { f($1); } If $options = 'hello' then the call to f($1) breaks. The regexp match inside f() silently changes f's arguments. This is not such a contrived example; Date::Manip has functions like this. It is a good idea to unpack @_ first, but not passing $1 as an argument is a sensible precaution if calling third-party code that might not always follow that rule.
In progress, as Perl::Critic::Policy::Subroutine::ProhibitPassingCaptureVariable. No code committed to SVN yet, because of false positives in the authortest suite. Tom Wyant
Proposed new policy Subroutines::ProhibitPassingCaptureVariable committed to branch rt38289 as SVN revision 3168.