perl - Why does encode raise "Use of uninitialized value within @_"? -


with perl v5.14.2 (provided debian wheezy) code:

use encode qw(encode); no warnings "all";  sub test_encode {   return encode::encode("utf8", $_[0]); }  $a=undef; $r=test_encode(substr($a,0,1)); 

produces empty string in $r. i'm fine that.


with perl 5.18.2 (ubuntu 14.04), appears produces output:

use of uninitialized value within @_ in list assignment @ /usr/lib/perl/5.18/encode.pm line 147.

(even warnings disabled in main scop, apparently it's not warning. edit: per answers, it's warning):

that list assignment be, in encode.pm:

 146 sub encode($$;$) {  147     ( $name, $string, $check ) = @_;  148     return undef unless defined $string;  149     $string .= '';    # stringify; 

tweaking code, if undef passed encode instead of $_[0], no longer complains. if copy of $_[0] in temp variable passed instead of $_[0], doesn't complain too.

my question are: have changed in perl between these versions explain new behavior? perl see inside @_ in encode.pm line 147 ?


addendum: adding dump($_[0]); devel::peek @ start of test_encode, outputs:

perl 5.14.2:

 sv = pvlv(0x23a2c10) @ 0x2340998   refcnt = 1   flags = (gmg,smg)   iv = 0   nv = 0   pv = 0   magic = 0x235f950     mg_virtual = &pl_vtbl_substr     mg_type = perl_magic_substr(x)   type = x   targoff = 0   targlen = 0   targ = 0x235e370   sv = pv(0x233ec20) @ 0x235e370     refcnt = 2     flags = (padmy,pok,ppok)     pv = 0x23576b0 ""\0     cur = 0     len = 16 

perl 5.18.2:

 sv = pvlv(0x25c07c0) @ 0x2546cb8   refcnt = 1   flags = (gmg,smg)   iv = 0   nv = 0   pv = 0   magic = 0x2567dd0     mg_virtual = &pl_vtbl_substr     mg_type = perl_magic_substr(x)   type = x   targoff = 0   targlen = 1   targ = 0x256f328   flags = 0   sv = null(0x0) @ 0x256f328     refcnt = 2     flags = (padmy) 

not sure think of that, sv part @ end differs significantly, looks empty string versus null(0x0).

it's substr that's warning.


substr warns when first argument undefined.

$ perl -we'    $x;    $y = substr($x, 0, 1);   # line 3 ' use of uninitialized value $x in substr @ -e line 3. 

since 5.16.0, warning happens when substring operation performed instead of when substr called. when substr used lvalue, actual substring operation performed when value fetched or stored in returned scalar.

$ perl -we'    $x;    $r = \substr($x, 0, 1);    $y = $$r;                # line 4 ' use of uninitialized value in scalar assignment @ -e line 4. 

the substring operation done allow following work:

$ perl -we'$_ = "abc"; substr($_, 0, 1) = "!!!"; say' !!!bc 

since warning happens when substring operation done, it's context of op in encode determines whether warning visible or not.

$ 5.14.2t/bin/perl -e'use warnings; $r = \substr(my $x, 0, 1); no  warnings; $y = $$r;' use of uninitialized value in scalar assignment @ -e line 1.  $ 5.14.2t/bin/perl -e'no  warnings; $r = \substr(my $x, 0, 1); use warnings; $y = $$r;'  $ 5.22.0t/bin/perl -e'use warnings; $r = \substr(my $x, 0, 1); no  warnings; $y = $$r;'  $ 5.22.0t/bin/perl -e'no  warnings; $r = \substr(my $x, 0, 1); use warnings; $y = $$r;' use of uninitialized value in scalar assignment @ -e line 1. 

why did warning starting happening substring operation perform instead of when substr called? i'm guessing, might fix following , similar problems:

$ perl -we'     $x = "def";     $r = \substr($x, 0, 1);     $x = "abc";     "<$$r>"; ' <a>  $ 5.14.2t/bin/perl -we'     $x;     $r = \substr($x, 0, 1);     $x = "abc";     "<$$r>"; ' use of uninitialized value $x in substr @ -e line 4. <>  $ 5.22.0t/bin/perl -we'     $x;     $r = \substr($x, 0, 1);     $x = "abc";     "<$$r>"; ' <a> 

prefixing substr scalar calls rvalue, though that's not documented.

$ perl -mo=concise,-exec -e'1        substr($_, 0, 1)' 2>&1 | grep substr 7  <@> substr[t4] skm/3                     ^                    flag causes special lvalue behaviour.  $ perl -mo=concise,-exec -e'1 scalar substr($_, 0, 1)' 2>&1 | grep substr 7  <@> substr[t2] sk/3 

you force stringification.

$ perl -mo=concise,-exec -e'1     "".substr($_, 0, 1)' 2>&1 | grep substr 8  <@> substr[t2] sk/3 

Comments

Popular posts from this blog

Fail to load namespace Spring Security http://www.springframework.org/security/tags -

sql - MySQL query optimization using coalesce -

unity3d - Unity local avoidance in user created world -