summaryrefslogtreecommitdiff
path: root/gv.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-10-21 05:58:40 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-10-21 22:12:59 -0700
commitb82b06b8ca329f89b70366e25afb8e2be30b446e (patch)
tree2048b9c510b101230175661356eae7ca5d1f4ba6 /gv.c
parent0be9b861b326969b378910bfcdea3f19d0d42992 (diff)
downloadperl-b82b06b8ca329f89b70366e25afb8e2be30b446e.tar.gz
Reimplement $[ as a module
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.
Diffstat (limited to 'gv.c')
-rw-r--r--gv.c24
1 files changed, 17 insertions, 7 deletions
diff --git a/gv.c b/gv.c
index 1319970e87..0010da7d3e 100644
--- a/gv.c
+++ b/gv.c
@@ -1278,6 +1278,7 @@ S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methp
char varname = *varpv; /* varpv might be clobbered by load_module,
so save it. For the moment it's always
a single char. */
+ const char type = varname == '[' ? '$' : '%';
dSP;
ENTER;
if ( flags & 1 )
@@ -1289,11 +1290,11 @@ S_require_tie_mod(pTHX_ GV *gv, const char *varpv, SV* namesv, const char *methp
SPAGAIN;
stash = gv_stashsv(namesv, 0);
if (!stash)
- Perl_croak(aTHX_ "panic: Can't use %%%c because %"SVf" is not available",
- varname, SVfARG(namesv));
+ Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" is not available",
+ type, varname, SVfARG(namesv));
else if (!gv_fetchmethod(stash, methpv))
- Perl_croak(aTHX_ "panic: Can't use %%%c because %"SVf" does not support method %s",
- varname, SVfARG(namesv), methpv);
+ Perl_croak(aTHX_ "panic: Can't use %c%c because %"SVf" does not support method %s",
+ type, varname, SVfARG(namesv), methpv);
}
SvREFCNT_dec(namesv);
return stash;
@@ -1659,12 +1660,15 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
if (add) {
GvMULTI_on(gv);
gv_init_svtype(gv, sv_type);
- if (len == 1 && stash == PL_defstash
- && (sv_type == SVt_PVHV || sv_type == SVt_PVGV)) {
+ if (len == 1 && stash == PL_defstash) {
+ if (sv_type == SVt_PVHV || sv_type == SVt_PVGV) {
if (*name == '!')
require_tie_mod(gv, "!", newSVpvs("Errno"), "TIEHASH", 1);
else if (*name == '-' || *name == '+')
require_tie_mod(gv, name, newSVpvs("Tie::Hash::NamedCapture"), "TIEHASH", 0);
+ }
+ if ((sv_type==SVt_PV || sv_type==SVt_PVGV) && *name == '[')
+ require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
}
else if (len == 3 && sv_type == SVt_PVAV
&& strnEQ(name, "ISA", 3)
@@ -1940,6 +1944,13 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
hv_magic(hv, NULL, PERL_MAGIC_hints);
}
goto magicalize;
+ case '[': /* $[ */
+ if (sv_type == SVt_PV || sv_type == SVt_PVGV) {
+ if (addmg) (void)hv_store(stash,name,len,(SV *)gv,0);
+ require_tie_mod(gv,name,newSVpvs("arybase"),"FETCH",0);
+ addmg = 0;
+ }
+ break;
case '\023': /* $^S */
ro_magicalize:
SvREADONLY_on(GvSVn(gv));
@@ -1954,7 +1965,6 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags,
case '7': /* $7 */
case '8': /* $8 */
case '9': /* $9 */
- case '[': /* $[ */
case '^': /* $^ */
case '~': /* $~ */
case '=': /* $= */