in reply to cpan install($_) doesn't work in loop, but normal lexical var does

This is happening because somewhere in the install process an unlocalized $_ is being assigned to.

The same error will occur with the following:

for ( "a" ) { $_ = 1; } # Or for ( "a" ) { while (<>){ } }

The magic of $_ is too fragile for anything but simple cases in my opinion. Do this instead:

for my $module ('Catalyst::Plugin::Authentication') { }

Replies are listed 'Best First'.
Re^2: cpan install($_) doesn't work in loop, but normal lexical var does
by xdg (Monsignor) on Aug 27, 2006 at 20:09 UTC

    Is your ExtUtils::MakeMaker older than 6.18? parse_version used to blow away an existing $_. (I just discovered that this morning, in fact.)

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re^2: cpan install($_) doesn't work in loop, but normal lexical var does
by doom (Deacon) on Aug 27, 2006 at 22:58 UTC
    The magic of $_ is too fragile for anything but simple cases in my opinion.
    Yes, but it's the authors of CPAN modules that should be watching out for this, not the users of the modules.

    Something I've wondered about off-and-on: is there any compelling reason not to do a "local $_;" at the beginning of every subroutine, unless you're relying on a value being passed in via $_? Why isn't this one of our "best practices"?

      "...is there any compelling reason not to do a "local $_;" at the beginning of every subroutine?"

      Yes, doesn't fix the problem. Any time you call a function, subroutine or method it could blow away $_. And you will never have control of other peoples code so if you rely on $_ not being hosed you'll eventually get burnt. Far better is to practice defensive programing and not rely on $_ after all the perl syntax in all cases allows you to specify something other that the default input/output scalar.


      s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
        "...is there any compelling reason not to do a "local $_;" at the beginning of every subroutine?"
        Yes, doesn't fix the problem. Any time you call a function, subroutine or method it could blow away $_. And you will never have control of other peoples code so if you rely on $_ not being hosed you'll eventually get burnt.
        And by the same token, if you're a module author, you have no control over your user's code, and if you're stomping on $_, eventually one of them will be burned by it.

        So if you don't want to burn your users, you should always localize $_.