summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2013-07-15 23:51:15 -0700
committerFather Chrysostomos <sprout@cpan.org>2013-07-16 00:26:02 -0700
commit13733cde3fe669aafa0a2a598b5b45d024fb3b86 (patch)
tree34c6d12801583e3d88fe5372be078965373b8f0e /pp_sys.c
parentd4431b89a00a340cc459be515feeb6c274012420 (diff)
downloadperl-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.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 793de406b3..2aa83a803e 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -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;