...the output of the above reads...my @a = qw[a simple list]; Internals::SvREADONLY(@a, 1); Internals::SvREADONLY($a[1], 1); # Make our target element RO (dou +ble sure!) warn '$a[1] is ' . (Internals::SvREADONLY($a[1]) ? '' : 'not ') . +'read-only'; warn join ' ', @a; eval { $a[1] = 'changed' }; # Modification of a read-only val +ue attempted warn join ' ', @a; splice(@a, 1, 1, 'spliced'); warn join ' ', @a; warn '$a[1] is ' . (Internals::SvREADONLY($a[1]) ? '' : 'not ') . +'read-only';
$a[1] is read-only at debug.pl line 3.
a simple list at debug.pl line 4.
a simple list at debug.pl line 6.
a spliced list at debug.pl line 8.
$a[1] is not read-only at debug.pl line 9.
splice(...) can replace read-only elements where setting them with an operator throws an exception because the actual element is replaced internally rather than just the value. ...even though the container is immutable. splice(...) can also delete elements from a immutable array where delete() will fail:
It's been a long day but to me, this is unexpected behavior. It's certainly low priority (due to it being a feature of Internals::) but before I report it as a bug on RT, I'm seeking opinions.my @b = qw[another simple list]; Internals::SvREADONLY(@b, 1);# Matters here warn join ' ', @b; # "another simple list" eval { delete $b[1] }; # throws Modification of... warn join ' ', @b; # "another simple list" splice(@b, 1, 1); # Zot! warn join ' ', @b; # "another list"
Code tested on Strawberry Perl v5.20.1 (MSWin32-x64-multi-thread) but this originally came to me years ago.
In reply to Calling splice() on Immutable Arrays by SankoR
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |