in reply to Re^2: Warnings on unused variables?
in thread Warnings on unused variables?

I'm a little confused here... why would that trigger an unused warning? The variables in the calling code will be used, and the receiving function will be declaring its own, assigning out of @_, and discarding the rest, so it shouldn't have a problem either.

Could you post an example?

Replies are listed 'Best First'.
Re^4: Warnings on unused variables?
by Animator (Hermit) on Sep 29, 2008 at 19:22 UTC

    For example:

    sub foo1 { my ($c, $d, $e, $f) = @_; return $d * f; } sub foo2 { my ($c, $d, $e, $f) = @_; return $c + $d + $e + $f; } sub do_foo { my $which = $_[0] ? \&foo1, \&foo2; $which->(1, 2, 3, 4); }

    As you see foo1 uses only uses the second argument and fourth ($d, $f). But the assignment happens via my ($c, $d, $e, $f) = @_;. If a warnings is introduced for lexical variables that are used once then it will warn. (lexicals $c and $e are declared and initialized but never used.

    Yes, the assignment could be changed into: my ($d, $f) = @_[1, 3]; but this would be worse from a maintenance point of view.

    With my ($c, $d, $e, $f) = @_; you know exactly what parameters are passed (assuming they get a decent name). If you use my ($d, $f) = @_[1, 3]; then you are clueless about the other arguments.
    If you later need the other arguments then you need to start looking in what order they were passed.

      What I'm not seeing is why you would think that $c or $e could have a name better than undef.

      sub foo1 { my (undef, $d, undef, $f) = @_; return $d * $f; }
      ... works just fine, produces no warnings, and has the added advantage of immediately giving the parameter a name that makes it absolutely clear that the value will be discarded.

        Because it is easier for maintenance to name them from the beggining.

        Suppose you use my (undef, $d, undef, $f) = @_; and 2 months later you also need another variable. Then you need to go look to what code calls is then try to add the argument there - or find another way of passing it - and ultimetly find out it is already being passed as the 3th argument.

        A real live example is from a mod_perl framework that uses: my ($data, $p, $r, $dbh) = @_;.
        The explenation of the variables:

        • $data: The object of a data class that is linked with the module,
        • $p: A list of common arguments (who is logged in, what language, what level, ...),
        • $r: The Apache::Request object,
        • $dbh: The database connection,


        While most of the code will never use $r and $dbh it is still useful to store them in a lexical since it is immposible to predict how the subroutine will grow and when it will need them.

        What you call an advantage I call a serious disadvantage for maintenance. If you later need $r for some reason you need to look up as which argument it is passed.