I've got an edge case no one in their right mind would stumble upon. This time an oldie from the days when
Readonly::XS was needed but still matters today for
Readonly (edit: which I currently maintain),
Const::Fast (edit: which is the result of Readonly's inherently broken modus operandi), etc.; modules that wrap perl's own internal means of marking variables as read-only. Consider this:
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';
...the output of the above reads...
$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:
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"
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.
Code tested on Strawberry Perl v5.20.1 (MSWin32-x64-multi-thread) but this originally came to me years ago.
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.