diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2002-05-08 00:13:10 +0100 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 2002-05-07 22:23:34 +0000 |
commit | 8d1f198fe997a3eac9dc901e973cdc46ac8bbdec (patch) | |
tree | 07e0eb8e581ea5a539f7a8fcf662bcac98581fbf /pp_hot.c | |
parent | 386c44e5c8a5d040bf976283d7be37c363673092 (diff) | |
download | perl-8d1f198fe997a3eac9dc901e973cdc46ac8bbdec.tar.gz |
correctly unlocalise exists on tied/%ENV
Message-ID: <20020507231310.B4118@fdgroup.com>
p4raw-id: //depot/perl@16455
Diffstat (limited to 'pp_hot.c')
-rw-r--r-- | pp_hot.c | 22 |
1 files changed, 17 insertions, 5 deletions
@@ -1643,13 +1643,25 @@ PP(pp_helem) I32 preeminent = 0; if (SvTYPE(hv) == SVt_PVHV) { - if (PL_op->op_private & OPpLVAL_INTRO) + if (PL_op->op_private & OPpLVAL_INTRO) { + MAGIC *mg; + HV *stash; + /* does the element we're localizing already exist? */ preeminent = - ( SvRMAGICAL(hv) - && !mg_find((SV*)hv, PERL_MAGIC_tied) - && !mg_find((SV*)hv, PERL_MAGIC_env) - ) ? 1 : hv_exists_ent(hv, keysv, 0); + /* can we determine whether it exists? */ + ( !SvRMAGICAL(hv) + || mg_find((SV*)hv, PERL_MAGIC_env) + || ( (mg = mg_find((SV*)hv, PERL_MAGIC_tied)) + /* Try to preserve the existenceness of a tied hash + * element by using EXISTS and DELETE if possible. + * Fallback to FETCH and STORE otherwise */ + && (stash = SvSTASH(SvRV(SvTIED_obj((SV*)hv, mg)))) + && gv_fetchmethod_autoload(stash, "EXISTS", TRUE) + && gv_fetchmethod_autoload(stash, "DELETE", TRUE) + ) + ) ? hv_exists_ent(hv, keysv, 0) : 1; + } he = hv_fetch_ent(hv, keysv, lval && !defer, hash); svp = he ? &HeVAL(he) : 0; } |