Строка кода, которую я наивно думал, будет переводить буквально между Perl 6 и Perl 5, на самом деле это не так, из-за различий в способе обработки переменной после приращения.
Этот Perl 6 даетжелаемый результат, магический квадрат: [[8, 1, 6], [3, 5, 7], [4, 9, 2]]
my @sq; my $n = 3; my $i = 1; my $x = $n/2; my $y = 0;
@sq[($i%$n ?? $y-- !! $y++) % $n][($i%$n ?? $x++ !! $x) % $n] = $i++ for 0..$n**2 - 1;
say join ' ', $_ for @sq;
«Тот же» код в Perl 5не: [[8, 1, 3], [9, 5, 7], [4, 6, 2]]
$n = 3; $i = 1; $x = $n/2; $y = 0;
$sq[($i%$n ? $y-- : $y++) % $n][($i%$n ? $x++ : $x) % $n] = $i++ for 0..$n**2 - 1;
say join ' ', @$_ for @sq;
Оба работают правильно, если оператор разделен, и всеинкременты и декременты выполняются после присваивания, например, в Perl 5:
for (0 .. $n**2 - 1) {
$sq[ $y%$n ][ $x%$n ] = $i;
$i%$n ? $y-- : $y++;
$x++ if $i%$n;
$i++;
}
Если возвращаемое значение операции инкремента или декремента равно значению переменной до операции, то Perl5 будет неправильно.Но эксперименты с кодом показали, что результатом условий $i%$n
был источник различия, поэтому, по-видимому, Perl 6 может полагаться на значение $i
способом, который строго не гарантирован.
Таким образом, я должен был быть более удивлен, что Perl 6 работал, чем тот, который не Perl 5 не сделал?