This may be old news for seasoned module authors, but I just got bitten by a new bug I wasn't really aware of before.

While debugging a script using Mail::Audit::Attach, I was wondering why the script would die at a certain point (it called a method on an undefined value). Finally, I found out the reason. The code was something like this:

foreach (@attachments) { $_->method1; $_->method2; }

Unfortunately, method1 contained a loop using $_ and finally setting it to undef, thus causing the script to die on the next method call.

The funny thing is, I have used constructs like

{ local $/ = undef; $data = <FILE> }

a lot of times, but somehow the concept never transferred itself to $_.

The solution, of course, is to either not use $_, or insert

local $_

in each method/function that uses it.

update (broquaint): title clarification (s/clutter/clobber/)

Replies are listed 'Best First'.
Re: Is your module clobbering predefined variables?
by Mr. Muskrat (Canon) on Apr 14, 2003 at 13:46 UTC
    Programming Perl, 3rd Edition includes a nice little module that you might want to look at. It's called Underscore and you call it like: no Underscore; It simply warns you if you try to use $_ without localizing it.
      Cool! That's one for the debugging toolkit.. throw it at misbehaving scripts for a quick check, much like warnings and strict.

      Makeshifts last the longest.

      I started searching and wandered upon a cool link. Tom Christiansen posted the source for Underscore.pm as well as a test script (both of which appear in the Camel).

      Update! bikeNomad posted a similar one here and says it's from the Perl Cookbook.

Re: Is your module clobbering predefined variables?
by BUU (Prior) on Apr 14, 2003 at 03:24 UTC
    Thats a fun bug and looking at how it's implemented and so forth, you'd think that it would be a far more common error. But some how it seems to almost never conflict, I've only run into it once or twice myself. Possibly because the only time i really use $_ is in things that automagically localize it, such as for map grep
      You mean, you've never used
      while (<>) { ... }

      Because that's the most common construct that sets $_ without localizing it.

      Abigail

Re: Is your module clobbering predefined variables?
by bsb (Priest) on Apr 14, 2003 at 06:38 UTC
    I've had bugs with $@ getting mistakenly cleared in exception handling. Same kind of thing.

    s/clutter/clobber/g;

      s/clutter/clobber/g;

      This is obviously some strange usage of the word "clobber" that -- as a non-native speaker of English -- I wasn't previously aware of. The habit of beating up other people's variables and namespaces seems to be closely limited to the Perl community, though ;-). I did brief searches on google (which strongly leaned towards "clutter") and perldoc.com (strongly leaning towards "clobber").

      The things you learn on this site...

      Update: Thanks to Jenda and tye for the more in-depth information, and for broquaint to do the title editing.

        I'm definitely not the right person to respond (I'm not a native speaker either), but I understand the difference like this: clutter means putting one's garbage to somewhere it doesn't belong and thus making it hard to find the real stuff (like writing temporary files into the same directory as the data files and forgeting to delete them). On the other hand to clobber is to overwrite someone elses data.

        So in the first case the data are still there, but are hard(er) to find, while in the second they are gone.

        Getting back to Perl ... if you export all your symbols to the main namespace you are cluttering it and if you overwrite someone elses variable you are clobbering.

        Jenda
        Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.
           -- Rick Osborne

        Edit by castaway: Closed small tag in signature

        "clobber" is commonly used to mean "overwrite". This has been true for over a decade (csh has had a "noclobber" option for more than 10 years).

        Now "clobber a predefined variable" can be made more precise as "clobber a predefined variable's value". In the original(?) use of the term, it was a file that was being overwritten, which makes the distinction even less problematic since the clobbering of the file's contents was often accomplished by overwriting the file with a different file (now with the same name that the original file used to have) rather than by keeping the same file and just overwriting the contents of that file (but both were possible and the distinction was rarely important since the point was that your file's original data was no longer available via the original file name).

        So I find it natural to interpret "clobber a predefined variable" as "clobber a predefined variable's value" in the absence of any evidence that we are actually talking about the less-common act of removing variables from symbol tables or replacing them.

        "Clutter" certainly doesn't fit this case, as Jenda explains.

                        - tye