Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ember.js/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 为什么encode会提高;在@“uquot;中使用未初始化的值;?_Perl - Fatal编程技术网

Perl 为什么encode会提高;在@“uquot;中使用未初始化的值;?

Perl 为什么encode会提高;在@“uquot;中使用未初始化的值;?,perl,Perl,对于Perl v5.14.2(由Debian Wheezy提供),此代码: use Encode qw(encode); no warnings "all"; sub test_encode { return Encode::encode("utf8", $_[0]); } my $a=undef; my $r=test_encode(substr($a,0,1)); 在$r中生成空字符串。我同意 在Perl 5.18.2(Ubuntu 14.04)中,它似乎产生以下输出: 在@in

对于Perl v5.14.2(由Debian Wheezy提供),此代码:

use Encode qw(encode);
no warnings "all";

sub test_encode {
  return Encode::encode("utf8", $_[0]);
}

my $a=undef;
my $r=test_encode(substr($a,0,1));
$r
中生成空字符串。我同意


在Perl 5.18.2(Ubuntu 14.04)中,它似乎产生以下输出:

在@in列表赋值中使用未初始化的值 /usr/lib/perl/5.18/Encode.pm第147行

(即使在主范围中禁用了警告,显然这不是警告。编辑:根据答案,这肯定是警告):

该列表分配将在
Encode.pm
中:

 146 sub encode($$;$) {
 147     my ( $name, $string, $check ) = @_;
 148     return undef unless defined $string;
 149     $string .= '';    # stringify;
调整代码时,如果将
unde
传递给
encode
而不是
$\u0]
,则不再抱怨。如果在临时变量中传递的是
$\u0]
的副本,而不是
$\u0]
,它也不会抱怨

我的问题是:在这些版本之间,Perl会有什么变化来解释新的行为?Perl在Encode.pm第147行的
@
中到底看到了什么


附录:添加
Dump($u0])
Devel::Peek
test\u encode
开始时,它输出:

Perl 5.14.2:

SV = PVLV(0x23a2c10) at 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) at 0x235e370 REFCNT = 2 FLAGS = (PADMY,POK,pPOK) PV = 0x23576b0 ""\0 CUR = 0 LEN = 16 SV=0x2340998处的PVLV(0x23a2c10) REFCNT=1 标志=(GMG、SMG) IV=0 NV=0 PV=0 MAGIC=0x235f950 MG_VIRTUAL=&PL_vtbl_substr MG_TYPE=PERL_MAGIC_substr(x) 类型=x TARGOFF=0 TARGLEN=0 TARG=0x235e370 SV=0x235e370处的PV(0x233ec20) REFCNT=2 FLAGS=(PADMY、POK、pPOK) PV=0x23576b0”“\0 CUR=0 LEN=16 Perl 5.18.2:

SV = PVLV(0x25c07c0) at 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) at 0x256f328 REFCNT = 2 FLAGS = (PADMY) SV=0x2546cb8处的PVLV(0x25c07c0) REFCNT=1 标志=(GMG、SMG) IV=0 NV=0 PV=0 MAGIC=0x2567dd0 MG_VIRTUAL=&PL_vtbl_substr MG_TYPE=PERL_MAGIC_substr(x) 类型=x TARGOFF=0 TARGLEN=1 TARG=0x256f328 标志=0 SV=0x256f328处的NULL(0x0) REFCNT=2 FLAGS=(PADMY)
不知道该怎么想,但结尾的
SV
部分差别很大,看起来像是空字符串与空字符串(0x0)。

很有趣。如果你做了几乎相同的事情,但是:

my $a=undef;
my $b = substr($a,0,1);
my $r=test_encode($b);
它很好用

或:

所以我想我必须说-这与
substr
和上下文的返回值有关

例如,
@[0]
未定义-
@
未定义

$ perl -we'
   my $x;
   my $y = substr($x, 0, 1);   # Line 3
'
Use of uninitialized value $x in substr at -e line 3.
Encode
模块具有:

#
# $Id: Encode.pm,v 2.75 2015/06/30 09:57:15 dankogai Exp $
#
package Encode;
use strict;
use warnings;
这将覆盖您的
no warnings
指令,但是隐藏这样的警告并不是真正需要的。但这已经有一段时间了:

2.18 2006/06/03 20:28:48
! bin/enc2xs
  overhauled the -C option
  - added ascii-ctrl', 'null', 'utf-8-strict' to core
  - auto-generated Encode::ConfigLocal no longer use v-string for version
  - now searches modules via File::Find so Encode/JP/Mobile is happy
! Byte/Byte.pm CN/CN.pm EBCDIC/EBCDIC.pm JP/JP.pm KR/KR.pm Symbol/Symbol.pm
  use strict added; though all they do is load XS, it's
  still better a practice
! *.pm
  use warnings added to all of them for better practices' sake.

因此,我建议您在工作时使用旧版本的Encode

这是警告


substr
在其第一个参数未定义时发出警告

$ perl -we'
   my $x;
   my $y = substr($x, 0, 1);   # Line 3
'
Use of uninitialized value $x in substr at -e line 3.
,则警告现在在实际执行子字符串操作时发生,而不是在调用
substr
时发生。当
substr
用作左值时,实际的子字符串操作将在获取a值或将其存储在返回的标量中时执行

$ perl -we'
   my $x;
   my $r = \substr($x, 0, 1);
   my $y = $$r;                # Line 4
'
Use of uninitialized value in scalar assignment at -e line 4.
然后执行子字符串操作以允许以下操作:

$ perl -wE'$_ = "abc"; substr($_, 0, 1) = "!!!"; say'
!!!bc
由于警告现在在子字符串操作完成时发生,因此由op in Encode的上下文决定警告是否可见

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

$ 5.14.2t/bin/perl -e'no  warnings; my $r = \substr(my $x, 0, 1); use warnings; my $y = $$r;'

$ 5.22.0t/bin/perl -e'use warnings; my $r = \substr(my $x, 0, 1); no  warnings; my $y = $$r;'

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

为什么警告开始发生在实际执行子字符串操作的位置,而不是调用
substr
时?我猜,但可能是为了解决以下问题和类似问题:

$ perl -wE'
    my $x = "def";
    my $r = \substr($x, 0, 1);
    $x = "abc";
    say "<$$r>";
'
<a>

$ 5.14.2t/bin/perl -wE'
    my $x;
    my $r = \substr($x, 0, 1);
    $x = "abc";
    say "<$$r>";
'
Use of uninitialized value $x in substr at -e line 4.
<>

$ 5.22.0t/bin/perl -wE'
    my $x;
    my $r = \substr($x, 0, 1);
    $x = "abc";
    say "<$$r>";
'
<a>
你也可以强制严格化

$ perl -MO=Concise,-exec -e'1 for     "".substr($_, 0, 1)' 2>&1 | grep substr
8  <@> substr[t2] sK/3
$perl-MO=简明,-exec-e'1 for”“.substr($\u0,1)'2>&1 | grep substr
8 substr[t2]sK/3

@toolic:但是5.14(喘息)中的Encode.pm有
使用警告其中只有sameold Encode.pm是
$Id:Encode.pm,v2.42 2010/12/31 22:48:10 dankogai Exp
嗯,我将深入挖掘。我怀疑我们会发现这在
perldelta
的某个地方。Re“
@[0]
未定义-
@
未定义”,这毫无意义;数组不能未定义,只能为空。未定义的是LvTARG($\u0])
。因此,考虑到substr的延迟计算,有没有一种简单的方法可以使警告静音?(一开始避免
substr(undef,…)
。不使用
使用警告将使警告静音。。。但那不是你真正想要的。阅读我刚刚添加到底部的部分。琐事:返回可赋值的四个运算符:
substr
vec
$\array
$ perl -MO=Concise,-exec -e'1 for     "".substr($_, 0, 1)' 2>&1 | grep substr
8  <@> substr[t2] sK/3