In Python, if you index a collection structure with a out-of-bounds key/index, you get a slap in the face:
>>> [1, 2, 3][9]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range
That's an Exception; it derives from BaseException, and failing to handle one will crash my program, which is almost always what I want.
Perl 5 and 6's list indexing seems to not care about out-of-bounds indexing:
$ perl6
> my @l = (1..4);
[1 2 3 4]
> say @l[2];
3
> say @l[9];
(Any)
> print @l[9];
Use of uninitialized value @l of type Any in string context
<snip>
True
> my $x = @l[9]; # even assignment doesn't error! who decided this was okay!?
> say $x; print $x;
(Any)
Use of uninitialized value $x of type Any in string context
<snip>
it's basically the same thing in Perl 5, except you don't get a value returned, but execution continues as normal.
I don't understand why out-of-bounds accessing should ever be silent. The only warnings you get that value may be "uninitialised" (but we all know it really means non-existent) are when you give it to certain functions.
Can I fix this somehow? I could implement my own post-circumfix indexing operator to override the default one that dies on junk index, but there's no way to tell the difference between an uninitialised value and the type Any
. The only way to do that I can see is to check if the requested index is in the range List.elems()
.
What (preferably minimal, simple, clean, readable, etc) solution can I use to remedy this?
Before anyone says "yes, but the variable is uninitialised, like my $x;
!": in C you get a segfault if you access memory you didn't allocate; why can't I have that sort of safety?
I've tagged this as both Perl and Perl 6 because, while I'm learning Perl 6 and the particulars of this question apply mostly to 6, the main idea seems to be a shared aspect of both 5 and 6.