Почему только один из них говорит мне "Модификация значения, доступного только для чтения"?

Этот код запускается и выдает вывод abc:

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

Но этот код умирает с ошибкой Modification of a read-only value attempted at ...:

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

Почему эти конструкции обрабатываются по-разному?

(Этот код также работает:)

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

Ответ 1

Вероятно, из-за оптимизации цикла подсчета, которая входит в игру, когда вы foreach над диапазоном. for (1, 2, 3, 4) фактически создает список (1, 2, 3, 4), содержащий эти конкретные значения только для чтения, но for (1..4) не работает; он просто итерации начинается с начала диапазона до конца, давая $_ каждое последующее значение в свою очередь, и, я думаю, никто не думал, что было бы целесообразно сопоставить поведение, когда вы пытаетесь привязать к $_, что близко.

Ответ 2

Ваш последний фрагмент делает то, что он не должен. Это лучше всего продемонстрировать с помощью следующего кода:

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

Вывод:

123567
234678

RT # 3105


Насколько мне известно, существует три типа циклов для циклов:

  • "C-style" (for (my $i=1; $i<4; ++$i))
  • Итерация (for my $i (1,2,3))
  • Подсчет (for my $i (1..3))