Skip to content

Commit

Permalink
Reimplement $[ as a module
Browse files Browse the repository at this point in the history
This commit reimplements $[ using PL_check hooks, custom pp func-
tions and ties.

Outside of its compile-time use, $[ is now parsed as a simple varia-
ble, so function calls like foo($[) are permitted, which was not the
case with the former implementation removed by e1dccc0.  I consider
that a bug fix.

The ‘That use of $[ is unsupported’ errors are out of necessity
deferred to run-time and implemented by a tied $[.

Indices between 0 and the array base are now treated consistently, as
are indices between a negative array base and zero.  That, too, is
a bug fix.
  • Loading branch information
Father Chrysostomos committed Oct 22, 2011
1 parent 0be9b86 commit b82b06b
Show file tree
Hide file tree
Showing 26 changed files with 1,337 additions and 28 deletions.
17 changes: 17 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -3507,6 +3507,23 @@ epoc/epocish.c EPOC port
epoc/epocish.h EPOC port
epoc/epoc_stubs.c EPOC port
epoc/link.pl EPOC port link a exe
ext/arybase/arybase.pm For $[
ext/arybase/arybase.xs For $[
ext/arybase/Makefile.PL For $[
ext/arybase/ptable.h For $[
ext/arybase/t/aeach.t For $[
ext/arybase/t/aelem.t For $[
ext/arybase/t/akeys.t For $[
ext/arybase/t/arybase.t For $[
ext/arybase/t/aslice.t For $[
ext/arybase/t/av2arylen.t For $[
ext/arybase/t/index.t For $[
ext/arybase/t/lslice.t For $[
ext/arybase/t/pos.t For $[
ext/arybase/t/scope_0.pm For $[
ext/arybase/t/scope.t For $[
ext/arybase/t/splice.t For $[
ext/arybase/t/substr.t For $[
ext/attributes/attributes.pm For "sub foo : attrlist"
ext/attributes/attributes.xs For "sub foo : attrlist"
ext/B/B/Concise.pm Compiler Concise backend
Expand Down
1 change: 1 addition & 0 deletions Porting/Maintainers.pl
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,7 @@ package Maintainers;
{
'MAINTAINER' => 'p5p',
'FILES' => q[
ext/arybase/
ext/XS-APItest/
lib/CORE.pod
lib/Config.t
Expand Down
16 changes: 16 additions & 0 deletions ext/arybase/Makefile.PL
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use ExtUtils::MakeMaker;

WriteMakefile(
NAME => 'arybase',
VERSION_FROM => 'arybase.pm',
ABSTRACT_FROM => 'arybase.pm',
realclean => { FILES => "" },
);

# To work around nmake stupidity. See rt.cpan.org #71847.
package MY;
sub ppd {
my $stuff = SUPER::ppd{} @_;
$stuff =~ s/ \$\[/ \$\$[/;
$stuff;
}
98 changes: 98 additions & 0 deletions ext/arybase/arybase.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package arybase;

our $VERSION = "0.01";

require XSLoader;
XSLoader::load(); # This returns true, which makes require happy.

__END__
=head1 NAME
arybase - Set indexing base via $[
=head1 SYNOPSIS
$[ = 1;
@a = qw(Sun Mon Tue Wed Thu Fri Sat);
print $a[3], "\n"; # prints Tue
=head1 DESCRIPTION
This module implements Perl's C<$[> variable. You should not use it
directly.
Assigning to C<$[> has the I<compile-time> effect of making the assigned
value, converted to an integer, the index of the first element in an array
and the first character in a substring, within the enclosing lexical scope.
It can be written with or without C<local>:
$[ = 1;
local $[ = 1;
It only works if the assignment can be detected at compile time and the
value assigned is constant.
It affects the following operations:
$array[$element]
@array[@slice]
$#array
(list())[$slice]
splice @array, $index, ...
each @array
keys @array
index $string, $substring # return value is affected
pos $string
substr $string, $offset, ...
As with the default base of 0, negative bases count from the end of the
array or string, starting with -1. If C<$[> is a positive integer, indices
from C<$[-1> to 0 also count from the end. If C<$[> is negative (why would
you do that, though?), indices from C<$[> to 0 count from the beginning of
the string, but indices below C<$[> count from the end of the string as
though the base were 0.
Prior to Perl 5.16, indices from 0 to C<$[-1> inclusive, for positive
values of C<$[>, behaved differently for different operations; negative
indices equal to or greater than a negative C<$[> likewise behaved
inconsistently.
=head1 HISTORY
Before Perl 5, C<$[> was a global variable that affected all array indices
and string offsets.
Starting with Perl 5, it became a file-scoped compile-time directive, which
could be made lexically-scoped with C<local>. "File-scoped" means that the
C<$[> assignment could leak out of the block in which occurred:
{
$[ = 1;
# ... array base is 1 here ...
}
# ... still 1, but not in other files ...
In Perl 5.10, it became strictly lexical. The file-scoped behaviour was
removed (perhaps inadvertently, but what's done is done).
In Perl 5.16, the implementation was moved into this module, and out of the
Perl core. The erratic behaviour that occurred with indices between -1 and
C<$[> was made consistent between operations, and, for negative bases,
indices from C<$[> to -1 inclusive were made consistent between operations.
=head1 BUGS
Error messages that mention array indices use the 0-based index.
C<keys $arrayref> and C<each $arrayref> do not respect the current value of
C<$[>.
=head1 SEE ALSO
L<perlvar/"$[">, L<Array::Base> and L<String::Base>.
=cut
Loading

0 comments on commit b82b06b

Please sign in to comment.