diff options
author | Father Chrysostomos <sprout@cpan.org> | 2013-07-15 23:51:15 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2013-07-16 00:26:02 -0700 |
commit | 13733cde3fe669aafa0a2a598b5b45d024fb3b86 (patch) | |
tree | 34c6d12801583e3d88fe5372be078965373b8f0e /pp_sys.c | |
parent | d4431b89a00a340cc459be515feeb6c274012420 (diff) | |
download | perl-13733cde3fe669aafa0a2a598b5b45d024fb3b86.tar.gz |
[perl #27010] Make tie work through defelems
When elements of @_ refer to nonexistent hash or array elements, then
the magic scalar in $_[0] delegates all set/get actions to the element
in represents, vivifying it if needed.
tie/tied/untie, however, were not delegating to the element, but were
tying the the magical ‘deferred element’ scalar itself.
Diffstat (limited to 'pp_sys.c')
-rw-r--r-- | pp_sys.c | 10 |
1 files changed, 10 insertions, 0 deletions
@@ -899,6 +899,10 @@ PP(pp_tie) varsv = MUTABLE_SV(GvIOp(varsv)); break; } + if (SvTYPE(varsv) == SVt_PVLV && LvTYPE(varsv) == 'y') { + vivify_defelem(varsv); + varsv = LvTARG(varsv); + } /* FALL THROUGH */ default: methname = "TIESCALAR"; @@ -967,6 +971,9 @@ PP(pp_untie) if (isGV_with_GP(sv) && !SvFAKE(sv) && !(sv = MUTABLE_SV(GvIOp(sv)))) RETPUSHYES; + if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y' && + !(sv = defelem_target(sv, NULL))) RETPUSHUNDEF; + if ((mg = SvTIED_mg(sv, how))) { SV * const obj = SvRV(SvTIED_obj(sv, mg)); if (obj) { @@ -1005,6 +1012,9 @@ PP(pp_tied) if (isGV_with_GP(sv) && !SvFAKE(sv) && !(sv = MUTABLE_SV(GvIOp(sv)))) RETPUSHUNDEF; + if (SvTYPE(sv) == SVt_PVLV && LvTYPE(sv) == 'y' && + !(sv = defelem_target(sv, NULL))) RETPUSHUNDEF; + if ((mg = SvTIED_mg(sv, how))) { PUSHs(SvTIED_obj(sv, mg)); RETURN; |