Skip to content

Commit

Permalink
add list context tests to t/op/lvref.t
Browse files Browse the repository at this point in the history
Codify the existing behaviour of alias list assignment in list
context, e.g.

    .... = (  (\$x, \$y, \(@A)) = (....)  );
and
           (  (\$x, \$y, \(@A)) = (....)  ) = ....;

Whether the existing behaviour is sane is up for debate, but if
if we change it, it should be a deliberate choice, not an accidental
change not spotted by the existing tests.
  • Loading branch information
iabyn committed Nov 16, 2023
1 parent 5d65e37 commit 64d8ebe
Showing 1 changed file with 84 additions and 1 deletion.
85 changes: 84 additions & 1 deletion t/op/lvref.t
Expand Up @@ -5,7 +5,7 @@ BEGIN {
set_up_inc("../lib");
}

plan 170;
plan 198;

eval '\$x = \$y';
like $@, qr/^Experimental aliasing via reference not enabled/,
Expand Down Expand Up @@ -207,6 +207,89 @@ package ArrayTest {
}
is \@i, $old, '(\local @a) unwound';
}

# Test list assignments in both lval and rval list context
#
# Note that these tests essentially just codify current behaviour.
# Whether that behaviour is sane is a debatable point. (See
# http://nntp.perl.org/group/perl.perl5.porters/267074
# "refaliasing list assignment in list context")

{
# First, confirm behaviour in void context

{
my (@a, @b, $p);
my ($x, $y, $z) = qw(X Y Z);

(\$p, \(@a)) = (\$x, \$y, \$z);

is \$p, \$x, '(\$p, \(@a)) = ...; $p is alias';
is \$a[0], \$y, '(\$p, \(@a)) = ...; $a[0] is alias';
is \$a[1], \$z, '(\$p, \(@a)) = ...; $a[1] is alias';
}

# then confirm behaviour in scalar context

{
my (@a, @b, $p);
my ($x, $y, $z) = qw(X Y Z);

my $n = ((\$p, \(@a)) = (\$x, \$y, \$z));

is \$p, \$x, '$n = (\$p, \(@a)) = ...; $p is alias';
is \$a[0], \$y, '$n = (\$p, \(@a)) = ...; $a[0] is alias';
is \$a[1], \$z, '$n = (\$p, \(@a)) = ...; $a[1] is alias';
is $n, 3, '$n = (\$p, \(@a)) = ...; n is 3';
}

# Now the real tests, first in rvalue list context

{
my (@a, @b, $p);
my ($x, $y, $z) = qw(X Y Z);

@b = ((\$p, \(@a)) = (\$x, \$y, \$z));

is \$p, \$x, '@b = (\$p, \(@a) = ...); $p is alias';
is \$a[0], \$y, '@b = (\$p, \(@a) = ...); $a[0] is alias';
is \$a[1], \$z, '@b = (\$p, \(@a) = ...); $a[1] is alias';
ok ref $b[0], '@b = (\$p, \(@a) = ...); $b[0] is ref';
ok ref $b[1], '@b = (\$p, \(@a) = ...); $b[1] is ref';
ok ref $b[2], '@b = (\$p, \(@a) = ...); $b[2] is ref';
is $b[0], \$x, '@b = (\$p, \(@a) = ...); $b[0] is ref to alias';
is $b[1], \$y, '@b = (\$p, \(@a) = ...); $b[1] is ref to alias';
is $b[2], \$z, '@b = (\$p, \(@a) = ...); $b[2] is ref to alias';
}

# The same, now in lvalue list context
#
# Note that the outer assign just (uselessly) modifies temporary
# references to $x etc; it doesn't do any aliasing.

{
my (@a, @b, $p);
my ($x, $y, $z) = qw(X Y Z);
my ($rx, $ry, $rz) = \($x, $y, $z);

((\$p, \(@a)) = ($rx, $ry, $rz)) = \(qw(A B C));

is \$p, \$x, '(\$p, \(@a) = ...) = @b; $p is alias';
is \$a[0], \$y, '(\$p, \(@a) = ...) = @b; $a[0] is alias';
is \$a[1], \$z, '(\$p, \(@a) = ...) = @b; $a[1] is alias';
ok ref $rx, '(\$p, \(@a) = ...) = @b; $rx is still ref';
ok ref $ry, '(\$p, \(@a) = ...) = @b; $ry is still ref';
ok ref $rz, '(\$p, \(@a) = ...) = @b; $ry is still ref';
is $rx, \$x, '(\$p, \(@a) = ...) = @b; $rx is still ref to $x';
is $ry, \$y, '(\$p, \(@a) = ...) = @b; $ry is still ref to $y';
is $rz, \$z, '(\$p, \(@a) = ...) = @b; $rz is still ref to $z';
is $x, 'X', '(\$p, \(@a) = ...) = @b; $x is still X';
is $y, 'Y', '(\$p, \(@a) = ...) = @b; $y is still Y';
is $z, 'Z', '(\$p, \(@a) = ...) = @b; $z is still Z';
}
}


for (1,2) {
\my @x = [1..3],
\my(@y) = \3,
Expand Down

0 comments on commit 64d8ebe

Please sign in to comment.