Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Modification of a read-only value" on while loop with implicit $_ variable

Tags:

perl

I don't really understand why the following piece of perl code

#!/usr/bin/perl -w

use strict;
use warnings;

strange($_) for qw(a b c);

sub strange {
  open FILE, '<', 'some_file.txt' or die;
  while (<FILE>) { } # this is line 10
  close FILE;
}

Is throwing the following error

Modification of a read-only value attempted at ./bug.pl line 10.

Is this a bug? Or there is something I should know about the usage of the magic/implicit variable $_?

like image 567
Juan A. Navarro Avatar asked Oct 12 '11 11:10

Juan A. Navarro


2 Answers

The while (<fh>) construct implicitly assigns to the global variable $_.

This is described in perlop:

If and only if the input symbol is the only thing inside the conditional of a while statement (...), the value is automatically assigned to the global variable $_, destroying whatever was there previously. (...) The $_ variable is not implicitly localized. You'll have to put a local $_; before the loop if you want that to happen.

The error is thrown because $_ is initially aliased to a constant value ("a").

You can avoid this by declaring a lexical variable:

while (my $line = <FILE>) {
    # do something with $line
}
like image 165
Eugene Yarmash Avatar answered Oct 14 '22 22:10

Eugene Yarmash


Yes, the while-loop reads into $_ which at that point is aliased to a constant (the string "a"). You should use local $_; before the while-loop, or read into a separate variable.

like image 26
Kusalananda Avatar answered Oct 14 '22 20:10

Kusalananda