Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modification of a read-only value attempted at ... line .... in a foreach loop [duplicate]

Tags:

perl

This code runs and produces the output abc:

for(10..12){$_=sprintf"%x",$_;print}

But this code dies with a Modification of a read-only value attempted at ... error:

for(10,11,12){$_=sprintf"%x",$_;print}

Why are these constructions treated differently?

(This code also works:)

for(10..10,11..11,12..12){$_=sprintf"%x",$_;print}
like image 286
mob Avatar asked Jan 26 '26 02:01

mob


2 Answers

Probably because of the "counting loop" optimization that comes into play when you foreach over a range. for (1, 2, 3, 4) actually constructs the list (1, 2, 3, 4), containing those particular readonly values, but for (1..4) doesn't; it just iterates from the start of the range to the end, giving $_ each successive value in turn, and I guess nobody thought it would be worthwhile to match the behavior when you try to assign to $_ that closely.

like image 181
hobbs Avatar answered Jan 28 '26 19:01

hobbs


Your last snippet is doing something it shouldn't. It's best demonstrated with the following code:

for (1..2) {
   for (1..3, 5..7) {
      print $_++;
   }
   print "\n";
}

Output:

123567
234678

RT#3105


As far as I'm concerned, there are three kinds of for loops:

  • "C-style" (for (my $i=1; $i<4; ++$i))
  • Iterating (for my $i (1,2,3))
  • Counting (for my $i (1..3))
like image 34
ikegami Avatar answered Jan 28 '26 20:01

ikegami