diff options
author | Father Chrysostomos <sprout@cpan.org> | 2012-10-16 16:07:19 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2012-10-16 16:07:19 -0700 |
commit | 0f43fd573c94446b795d95875cb722dd3f61d1fd (patch) | |
tree | 45028462f286a87b798eadf64ae531bee9076d39 /pp.c | |
parent | 6a97c51d3ccb6044a8e13896ba95a46e330ffa4b (diff) | |
download | perl-0f43fd573c94446b795d95875cb722dd3f61d1fd.tar.gz |
[perl #115260] Stop length($obj) from returning undef
When commit 9f621bb00 made length(undef) return undef, it also made it
return undef for objects with string overloading that returns undef.
But stringifying as undef is a contradiction in terms, and this makes
length inconsistent with defined, which returns true for such objects.
Changing this allows is to simplify pp_length, as we can now call
sv_len_utf8 on the argument unconditionally (except under the bytes
pragma). sv_len_utf8 is now careful not to record caches on magical
or overloaded scalars (any non-PV, in fact).
Note that sv_len is now just a wrapper around SvPV_const, so we use
SvPV_const_nomg, as there is no equivalent sv_len_nomg.
Diffstat (limited to 'pp.c')
-rw-r--r-- | pp.c | 35 |
1 files changed, 8 insertions, 27 deletions
@@ -2888,35 +2888,16 @@ PP(pp_length) dVAR; dSP; dTARGET; SV * const sv = TOPs; - if (SvGAMAGIC(sv)) { - /* For an overloaded or magic scalar, we can't know in advance if - it's going to be UTF-8 or not. Also, we can't call sv_len_utf8 as - it likes to cache the length. Maybe that should be a documented - feature of it. - */ - STRLEN len; - const char *const p - = sv_2pv_flags(sv, &len, - SV_UNDEF_RETURNS_NULL|SV_CONST_RETURN|SV_GMAGIC); - - if (!p) { - if (!SvPADTMP(TARG)) { - sv_setsv(TARG, &PL_sv_undef); - SETTARG; - } - SETs(&PL_sv_undef); - } - else if (DO_UTF8(sv)) { - SETi(utf8_length((U8*)p, (U8*)p + len)); - } - else - SETi(len); - } else if (SvOK(sv)) { - /* Neither magic nor overloaded. */ + SvGETMAGIC(sv); + if (SvOK(sv)) { if (!IN_BYTES) - SETi(sv_len_utf8(sv)); + SETi(sv_len_utf8_nomg(sv)); else - SETi(sv_len(sv)); + { + STRLEN len; + (void)SvPV_nomg_const(sv,len); + SETi(len); + } } else { if (!SvPADTMP(TARG)) { sv_setsv_nomg(TARG, &PL_sv_undef); |