使用软件包定界符时,perl字符串插值



正在与一些遗产perl作战,看起来如下:

sub UNIVERSAL::has_sub_class {
    my ($package,$class) = @_;
    my $all = all_packages();
    print "$package - $class", "n";
    print "$package::$class", "n";
    return exists $all->{"$package::$class"};
}

在两个不同的系统上,两个不同的perl安装/版本,此代码的行为不同,即"$package::$class"构造正确解决到一个系统上正确的软件包名称,但在另一个系统上不正确。

在两个不同系统上运行has_sub_class时,可以看到以下不同的print输出:

# print output on system 1 (perl v5.8.6):
webmars::parameter=HASH(0xee93d0) - webmars::parameter::date
webmars::parameter::date
# print output on system 2 (perl v5.18.1):
webmars::parameter=HASH(0x251c500) - webmars::parameter::date
webmars::parameter=HASH(0x251c500)::webmars::parameter::date

您知道可能导致这种行为的Perl V5.8.6和Perl v5.18.1之间有任何字符串插值变化吗?还是我应该看其他地方?我确实尝试了Google-ing-ing,并阅读Perl Change Notes,但找不到任何感兴趣的内容。

在我对Perl的有限了解的情况下,我尝试获取最小的代码,这些代码可能会重现我遇到的问题。我想出以下内容,希望与之相关:

# system 1 (perl v5.8.6):
$ perl -e 'my %x=(),$x=bless(%x),$y='bar';print "$x::$yn";'
bar
# system 2 (perl v5.18.1):
$ perl -e 'my %x=(),$x=bless(%x),$y='bar';print "$x::$yn";'
main=HASH(0xec0ce0)::bar

输出不同!有什么想法吗?

较短的演示:

($x::, $x) = (1,2);  print "$x::$x"
$ perl5.16.3 -e '($x::, $x) = (1,2);  print "$x::$x"'
12
$ perl5.18.1 -e '($x::, $x) = (1,2);  print "$x::$x"'
2::2

变暖。

$ perl5.16.3 -MO=Concise =e 'print "$x::$x"'
8  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
7     <@> print vK ->8
3        <0> pushmark s ->4
-        <1> ex-stringify sK/1 ->7
-           <0> ex-pushmark s ->4
6           <2> concat[t3] sK/2 ->7
-              <1> ex-rv2sv sK/1 ->5
4                 <#> gvsv[*x::] s ->5          <-     $x::
-              <1> ex-rv2sv sK/1 ->6
5                 <#> gvsv[*x] s ->6            <-     $x
-e syntax OK
$ perl5.18.1 -MO=Concise -e 'print "$x::$x"'
a  <@> leave[1 ref] vKP/REFC ->(end)
1     <0> enter ->2
2     <;> nextstate(main 1 -e:1) v:{ ->3
9     <@> print vK ->a
3        <0> pushmark s ->4
-        <1> ex-stringify sK/1 ->9
-           <0> ex-pushmark s ->4
8           <2> concat[t4] sKS/2 ->9
6              <2> concat[t2] sK/2 ->7
-                 <1> ex-rv2sv sK/1 ->5
4                    <#> gvsv[*x] s ->5         <-     $x
5                 <$> const[PV "::"] s ->6      <-     "::"
-              <1> ex-rv2sv sK/1 ->8
7                 <#> gvsv[*x] s ->8            <-     $x
-e syntax OK

tl; dr。v5.16解析"$x::$x"$x:: . $x。v5.18为$x . "::" . $x。我没有看到关于三角洲文档中这种更改的明显参考,但我会继续寻找。

所以,我的快速测试确认了问题 - 使用

perl -Mstrict -we 'my %x=(),$x=bless(%x),$y="bar";print "$x::$yn";'

(使用您的版本,我会收到" bar'的裸词警告)。

我在5.8.8中遇到的错误是"在串联中使用非初始化值"。

区别似乎是当我使用perl -MO=Deparse运行时,我会得到:

my ( %x ) = ();
my $x = bless ( %x );
my $y = 'bar';
print "$x::$yn";

如果我在5.20.2上运行,我会得到:

my ( %x ) = ();
my $x = bless ( %x );
my $y = 'bar';
print "${x}::$yn";

是的,是的,相同代码的解析方式发生了变化。但是我不确定这对您有何帮助,除了启发您的情况外,这还会发生什么?

最新更新