Professional Web Applications Themes

TIP: Use local when assigning to $_ - PERL Beginners

[I see this a lot on these groups. I know most of the time it is just used for examples, but I thought I would point out that it is a bad habit.] Anytime you make a direct assignment to the special variable $_, you should local-ize it. This code demonstrates the problem: #!/usr/bin/perl use strict; use warnings; my array = (1..5); sub nl { $_ = "\n"; print; } foreach (array) { nl; print; } __END__ The foreach assigns each element of array to the special variable $_. Then the function nl() is called. The first thing it does ...

  1. #1

    Default TIP: Use local when assigning to $_

    [I see this a lot on these groups. I know most of the time it is just
    used for examples, but I thought I would point out that it is a bad habit.]

    Anytime you make a direct assignment to the special variable $_, you
    should local-ize it. This code demonstrates the problem:

    #!/usr/bin/perl

    use strict;
    use warnings;

    my array = (1..5);

    sub nl {
    $_ = "\n";
    print;
    }

    foreach (array) {
    nl;
    print;
    }

    __END__

    The foreach assigns each element of array to the special variable $_.
    Then the function nl() is called. The first thing it does is assign a
    value to $_ which clobbers the previous value. That value is then
    printed as the implied default argument to print. Control returns from
    the function and print is called again with the implied default value in
    $_ which is still the value assigned in nl rather than the value
    assigned by foreach.

    Localizing by changing the assignment in nl() to:

    local $_ = "\n";

    results in the correct output. The assignment is made local to the
    enclosing scope, which in this case is the nl() function. When that
    scope is entered the old value of $_ is saved before any assignment is
    made. Then when the scoped is exited, the old value is restored.

    Randy.
    Randy Guest

  2. #2

    Default Re: TIP: Use local when assigning to $_

    On Jul 15, Randy W. Sims said:
     

    I have "better" code that demonstrates the problem:

    # scans a file for a string
    sub scanf {
    my ($file, $string) = _;
    open F, "< $file";
    while (<F>) {
    return 1 if /\Q$string/;
    }
    close F;
    return;
    }

    for (files) {
    if (scanf($_, "some string")) {
    push matches, $_;
    }
    }

    Using the <FH> operator implicitly assigns to $_, without localizing it.
    Therefore, if you're going to use 'while (<FH>)', please local()ize $_
    first.

    --
    Jeff "japhy" Pinyan % How can we ever be the sold short or
    RPI Acacia Brother #734 % the cheated, we who for every service
    http://japhy.perlmonk.org/ % have long ago been overpaid?
    http://www.perlmonks.org/ % -- Meister Eckhart

    Jeff Guest

  3. #3

    Default Re: TIP: Use local when assigning to $_

    Jeff 'japhy' Pinyan wrote: 
    >
    >
    > I have "better" code that demonstrates the problem:[/ref]

    Thanks. That's a much better and less contrived example.
     

    That's got me wondering: are there any more operators or constructs that
    clobber $_ ? A few experiments show that C<for>, C<map> all localize $_.
    Am I missing any?

    Not that I ever run into this anyway as I generally use an explicit
    variable:

    foreach my $elem (array)

    or my version of the while (<FH>) in your example would probably be
    something like:

    while (defined( my $line = <FH> ))

    Randy.
    Randy Guest

  4. #4

    Default Re: TIP: Use local when assigning to $_

    On Jul 15, Randy W. Sims said:
     
    >
    >That's got me wondering: are there any more operators or constructs that
    >clobber $_ ? A few experiments show that C<for>, C<map> all localize $_.[/ref]

    I don't believe any of them clobber $_. The only reason <FH> does is
    because the construct:

    while (<FH>)

    is turned into

    while ($_ = <FH>)

    which in turn becomes

    while (defined($_ = <FH>))

    Which is why you never have to write

    while (defined(my $x = <FH>))

    because Perl turns

    while (my $x = <FH>)

    into that for you.

    --
    Jeff "japhy" Pinyan % How can we ever be the sold short or
    RPI Acacia Brother #734 % the cheated, we who for every service
    http://japhy.perlmonk.org/ % have long ago been overpaid?
    http://www.perlmonks.org/ % -- Meister Eckhart

    Jeff Guest

Similar Threads

  1. Problem with local file and local link
    By leofire in forum Macromedia Flash Player
    Replies: 0
    Last Post: February 9th, 09:35 AM
  2. [PHP-DEV] Assigning to $this
    By Jan in forum PHP Development
    Replies: 8
    Last Post: February 4th, 04:21 PM
  3. Replies: 1
    Last Post: June 26th, 09:17 PM

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139