develooper Front page | perl.perl5.porters | Postings from August 2019

[perl #134337] Wrong aliasing of $_

Thread Previous
From:
Tony Cook via RT
Date:
August 5, 2019 00:07
Subject:
[perl #134337] Wrong aliasing of $_
Message ID:
rt-4.0.24-27478-1564963612-1518.134337-15-0@perl.org
On Sun, 04 Aug 2019 02:23:49 -0700, tomash.brechko@gmail.com wrote:
> This is a bug report for perl from tomash.brechko@gmail.com,
> generated with the help of perlbug 1.41 running under perl 5.28.2.
> 
> Not tested with v5.30, sorry.  With v5.28.2 the code below dies with
> "Modification of a read-only value attempted at -e line 9.":
> 
> $ echo 1 | perl -e '
>   use strict;
>   use warnings;
> 
> f($_) for "a";
> 
> sub f {
>     my ($v) = @_;
>     while (<STDIN>) { # line 9.
>         print "$v $_";
>     }
> }
> '

$_ is global, when you alias $_ it's aliased for all code.

When you alias $_ to a read-only value, and try to modify $_ the "Modification of a read-only value attempted at -e line 9." error is expected, not unusual.

Adding "local $_;" before the while loop in f() fixes this.

> However the problem is more severe: in a real-world program (that I
> can't provide, sorry again) in the code pattern
> 
> $/ = "\n";
> ...
> foreach (@a) {
>     warn "$_\n";  # Expect values of @a, but also get values read from
> $fh.
>     f($_);
> }
> ...
> sub f {
>     my ($v) = @_;
>     while (<$fh>) {
>        ...
>        $/ = "END\n";
>        <$fh>;
>        $/ = "\n";
>        last;
>     }
> }
> 
> warn() along with the values from @a also prints values read from $fh
> ($v in f() also gets values read from $fh, and the whole thing
> explodes).
> 
> Still I believe both cases are instances of the same problem:
> something is wrong with how $_ aliases its values.

Similarly here the while (<$fh>) in f() is modifying the elements of @a in the caller, again local fixes it.

$_ can be convenient, but it's like any other global, it can lead to unexpected action at a distance.

For complex code I tend to only use $_ with the aliasing done with operators like grep and map, and rarely with the statement modifier foreach.

This isn't a bug.

Tony

---
via perlbug:  queue: perl5 status: new
https://rt.perl.org/Ticket/Display.html?id=134337

Thread Previous


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About