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

"...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}
  • Comment on Re^3: cpan install($_) doesn't work in loop, but normal lexical var does
  • Download Code

Replies are listed 'Best First'.
Re^4: cpan install($_) doesn't work in loop, but normal lexical var does
by doom (Deacon) on Aug 28, 2006 at 02:29 UTC
    "...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 $_.

      Agreed!

      After I posted I was rethinking along those lines. Perl really makes it too easy to missuse globals. Anytime we are writing modules proper technique demands that we don't use any globals but there that default input/output space thing there just waiting to be defaulted to. I know that in the past I haven't thought about it much. Now that I have thought about I'm thinking I ought to write a test I could use on all modules in my system to check for abuse of $_.

      But then another part of me says, "It's just that, a global." Anyone can use it. Who's fault is it. The guy who use it in a subroutine or me who relied on it not being used?

      I'm in a quandry.

      Quandered in the Monastary; starbolin


      s//----->\t/;$~="JAPH";s//\r<$~~/;{s|~$~-|-~$~|||s |-$~~|$~~-|||s,<$~~,<~$~,,s,~$~>,$~~>,, $|=1,select$,,$,,$,,1e-1;print;redo}
        I hold the following rules assertions:

        1. module writing is about avoiding namespace clashing
        2. the proper use of globals in modules is the same as perl does with builtins like map and grep - aliasing them
        3. having $_ blown away is learning the hard way how to use globals properly: not to trust them once you give away control over them
        4. $_ isn't really a global, but a default - think scratchpad
        5. for really real global values everywhere, there is ${^_My_Real_Global_Var} - the "^_x" thingy (see perlvar at the end)

        So it's all about intent - if you inadvertently overwrite $_ or inadvertently get your $_ overwritten, it's fault in either way. If you do it deliberately, you'll do it (at best) for educational purposes - "hey, I wiped our scratchpad, isn't that nice? fix your code" :-)

        Anyways, I personally think $_ and friends should be seen as belonging to no namespace but the CORE, and closer to the default main namespace.

        --shmem

        <update> - added curlies for My_Real_Global_Var - thanks Hue-Bond </update>

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}