From: Rafael Garcia-Suarez Date: Sun, 23 Feb 2003 00:03:27 +0000 (+0100) Subject: Re: [perl #21321] local ${"FOO"} does not work X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=82d039840b913b4eed10833ac05709a5abd02ead;p=p5sagit%2Fp5-mst-13.2.git Re: [perl #21321] local ${"FOO"} does not work Message-Id: <20030223000327.6f0c11fa.rgarciasuarez@free.fr> p4raw-id: //depot/perl@18774 --- diff --git a/MANIFEST b/MANIFEST index 4695eb3..7ff5b2f 100644 --- a/MANIFEST +++ b/MANIFEST @@ -2591,6 +2591,7 @@ t/op/lex_assign.t See if ops involving lexicals or pad temps work t/op/lfs.t See if large files work for perlio t/op/list.t See if array lists work t/op/local.t See if local works +t/op/localref.t See if local ${deref} works t/op/loopctl.t See if next/last/redo work t/op/lop.t See if logical operators work t/op/magic.t See if magic variables work diff --git a/op.c b/op.c index fd853ae..e4f22cc 100644 --- a/op.c +++ b/op.c @@ -1053,8 +1053,6 @@ Perl_mod(pTHX_ OP *o, I32 type) case OP_RV2AV: case OP_RV2HV: - if (!type && cUNOPo->op_first->op_type != OP_GV) - Perl_croak(aTHX_ "Can't localize through a reference"); if (type == OP_REFGEN && o->op_flags & OPf_PARENS) { PL_modcount = RETURN_UNLIMITED_NUMBER; return o; /* Treat \(@foo) like ordinary list. */ @@ -1076,8 +1074,6 @@ Perl_mod(pTHX_ OP *o, I32 type) PL_modcount = RETURN_UNLIMITED_NUMBER; break; case OP_RV2SV: - if (!type && cUNOPo->op_first->op_type != OP_GV) - Perl_croak(aTHX_ "Can't localize through a reference"); ref(cUNOPo->op_first, o->op_type); /* FALL THROUGH */ case OP_GV: diff --git a/perl.h b/perl.h index d316734..f5a4d98 100644 --- a/perl.h +++ b/perl.h @@ -2933,6 +2933,8 @@ EXTCONST char PL_no_func[] INIT("The %s function is unimplemented"); EXTCONST char PL_no_myglob[] INIT("\"my\" variable %s can't be in a package"); +EXTCONST char PL_no_localize_ref[] + INIT("Can't localize through a reference"); EXTCONST char PL_uuemap[65] INIT("`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"); diff --git a/pp.c b/pp.c index cc6b5c3..2b15186 100644 --- a/pp.c +++ b/pp.c @@ -211,6 +211,7 @@ PP(pp_rv2gv) PP(pp_rv2sv) { + GV *gv = Nullgv; dSP; dTOPss; if (SvROK(sv)) { @@ -226,9 +227,9 @@ PP(pp_rv2sv) } } else { - GV *gv = (GV*)sv; char *sym; STRLEN len; + gv = (GV*)sv; if (SvTYPE(gv) != SVt_PVGV) { if (SvGMAGICAL(sv)) { @@ -265,8 +266,14 @@ PP(pp_rv2sv) sv = GvSV(gv); } if (PL_op->op_flags & OPf_MOD) { - if (PL_op->op_private & OPpLVAL_INTRO) - sv = save_scalar((GV*)TOPs); + if (PL_op->op_private & OPpLVAL_INTRO) { + if (cUNOP->op_first->op_type == OP_NULL) + sv = save_scalar((GV*)TOPs); + else if (gv) + sv = save_scalar(gv); + else + Perl_croak(aTHX_ PL_no_localize_ref); + } else if (PL_op->op_private & OPpDEREF) vivify_ref(sv, PL_op->op_private & OPpDEREF); } diff --git a/pp_hot.c b/pp_hot.c index 2991900..c82b2df 100644 --- a/pp_hot.c +++ b/pp_hot.c @@ -685,6 +685,9 @@ PP(pp_rv2av) SETs((SV*)av); RETURN; } + else if (PL_op->op_flags & OPf_MOD + && PL_op->op_private & OPpLVAL_INTRO) + Perl_croak(aTHX_ PL_no_localize_ref); } else { if (SvTYPE(sv) == SVt_PVAV) { @@ -809,6 +812,9 @@ PP(pp_rv2hv) SETs((SV*)hv); RETURN; } + else if (PL_op->op_flags & OPf_MOD + && PL_op->op_private & OPpLVAL_INTRO) + Perl_croak(aTHX_ PL_no_localize_ref); } else { if (SvTYPE(sv) == SVt_PVHV) { diff --git a/t/op/local.t b/t/op/local.t index 6da0391..1bb8b8a 100755 --- a/t/op/local.t +++ b/t/op/local.t @@ -45,10 +45,10 @@ print $a,@b,@c,%d,$x,$y; eval 'local($$e)'; print +($@ =~ /Can't localize through a reference/) ? "" : "not ", "ok 21\n"; -eval 'local(@$e)'; +eval '$e = []; local(@$e)'; print +($@ =~ /Can't localize through a reference/) ? "" : "not ", "ok 22\n"; -eval 'local(%$e)'; +eval '$e = {}; local(%$e)'; print +($@ =~ /Can't localize through a reference/) ? "" : "not ", "ok 23\n"; # Array and hash elements