正在打击一些遗留的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"
构造在一个系统上正确解析为正确的包名,但在另一个系统上没有。
在两个不同的系统上运行print
时,可以看到以下不同的has_sub_class
输出:
# 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-around并阅读perl更改说明,但找不到任何有趣的内容。
由于我对perl的了解有限,我尝试获得可以重现我遇到的问题的最小代码。我想出了以下内容,我希望这是相关的:
# system 1 (perl v5.8.6):
$ perl -e 'my %x=(),$x=bless(\%x),$y='bar';print "$x::$y\n";'
bar
# system 2 (perl v5.18.1):
$ perl -e 'my %x=(),$x=bless(\%x),$y='bar';print "$x::$y\n";'
main=HASH(0xec0ce0)::bar
输出不同!有什么想法吗?
答案 0 :(得分:4)
更短的演示:
($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
。我在delta docs中没有看到任何明显的变化,但我会继续寻找。
答案 1 :(得分:3)
所以,我的快速测试证实了这个问题 - 使用
perl -Mstrict -we 'my %x=(),$x=bless(\%x),$y="bar";print "$x::$y\n";'
(对于你的版本,我收到了'bar'的匿名警告)。
我在5.8.8中得到的错误是“在连接中使用未初始化的值”。
差异似乎是当我使用perl -MO=Deparse
时,我得到:
my ( %x ) = ();
my $x = bless ( \%x );
my $y = 'bar';
print "$x::$y\n";
如果我在5.20.2上运行,我会得到:
my ( %x ) = ();
my $x = bless ( \%x );
my $y = 'bar';
print "${x}::$y\n";
是的,解析相同代码的方式发生了变化。但是我不能完全确定这对你有什么帮助,除了可能会让你了解发生了什么?