Hi,

I have a simple script with a subroutine that I pass scalar & array arguments 
to,

        #!/usr/bin/perl

        use 5.01201;
        use strict;
        use warnings;

        my $this_fn = "input.txt";
        my @this_dr = qw(
          /path/1
          /path/2
        );
        my $this_rn = "recname";
        my $this_ad = "1.2.3.4.";

        sub modrec {
                my %args = %{ shift @_ };

                my $fn = $args{FN};
                my $ar = $args{AR};
                my $ad = $args{AD};
                my @dr = @{$args{DR}};

                return;
        }

        modrec (
         {
           FN=>$this_fn,
           DR=>\@this_dr,
           AR=>$this_rn,
           AD=>$this_ad,
         }
        );

The script *executes* just fine.

But when I exec perlcritic on it

        perlcritic --verbose 11 -harsh test.pl
                Always unpack @_ first at line 15, near 'sub modrec {'.
                  Subroutines::RequireArgUnpacking (Severity: 4)
                    Subroutines that use `@_' directly instead of unpacking the 
arguments to
                    local variables first have two major problems. First, they 
are very hard
                    to read. If you're going to refer to your variables by 
number instead of
                    by name, you may as well be writing assembler code! Second, 
`@_'
                    contains aliases to the original variables! If you modify 
the contents
                    of a `@_' entry, then you are modifying the variable 
outside of your
                    subroutine. For example:

                       sub print_local_var_plus_one {
                           my ($var) = @_;
                           print ++$var;
                       }
                       sub print_var_plus_one {
                           print ++$_[0];
                       }

                       my $x = 2;
                       print_local_var_plus_one($x); # prints "3", $x is still 2
                       print_var_plus_one($x);       # prints "3", $x is now 3 !
                       print $x;                     # prints "3"

                    This is spooky action-at-a-distance and is very hard to 
debug if it's
                    not intentional and well-documented (like `chop' or 
`chomp').

                    An exception is made for the usual delegation idiom
                    `$object->SUPER::something( @_ )'. Only `SUPER::' and 
`NEXT::' are
                    recognized (though this is configurable) and the argument 
list for the
                    delegate must consist only of `( @_ )'.

What's wrong with the way I'm unpacking the arguments passed to the subroutine,

        my %args = %{ shift @_ };

Is there a different, recommended way?

AJ

-- 
To unsubscribe, e-mail: beginners-unsubscr...@perl.org
For additional commands, e-mail: beginners-h...@perl.org
http://learn.perl.org/


Reply via email to