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.