在Perl中,我如何检查两个不同的可变对象的指针相等性?
由于在Perl中几乎所有东西都是可变的,因此有时可能需要知道两个对象何时相同 - 也就是说,修改一个对象会影响另一个对象。怎么能这样做?
编辑:“对象”是指任何Perl值。这包括字符串,数组,哈希等。
答案 0 :(得分:7)
如果您知道这两个值都是引用,则可以使用数字相等运算符==
来比较它们。
如果您不确定这两个值都是引用,则可以先使用ref
对其进行测试。
if (ref($x) and ref($y) and $x==$y) {
print "\$x and \$y are references to the same thing.\n"
}
perlref中记录了这一点,
使用字符串或数字作为参考会产生符号引用,如上所述。使用引用作为数字会生成一个整数,表示其在内存中的存储位置。要做的唯一有用的事情是用数字比较两个引用,看它们是否引用相同的位置。
答案 1 :(得分:5)
有时可能需要知道两个对象何时相同 - 也就是说,修改一个对象会影响另一个对象。怎么能这样做?
以下是使用此类检查的示例:
*d = \$x; # Makes $d an alias for $x.
($x, $y) = ($y, $x); # Requires creating temporary copies.
($x, $y) = ($m, $n); # Usually simple ($x=$m; $y=$m;)
($x, $y) = ($c, $d); # Requires creating temporary copies.
您可以看到检查here。
您不仅要检查两个"对象还是#34;是相同的,你想检查他们是否神奇。在上面的例子中,检查LHS上的变量" set"魔术,并检查RHS上的变量" get"魔法。
要检查分配给$dst
是否可以更改$src
,请使用以下内容:
use B qw( svref_2object SVs_GMG SVs_SMG );
use Scalar::Util qw( refaddr );
sub SvGMAGICAL { !!( svref_2object($_[0])->FLAGS & SVs_GMG ) }
sub SvSMAGICAL { !!( svref_2object($_[0])->FLAGS & SVs_SMG ) }
sub could_be_common {
my ($dst_ref, $src_ref) = @_;
my $dst_addr = refaddr($dst_ref) or die("usage");
my $src_addr = refaddr($src_ref) or die("usage");
return $dst_addr == $src_addr || SvSMAGICAL($dst_ref) || SvGMAGICAL($src_ref);
}
say could_be_common($dst, $src);
或者对于上面的例子,
sub could_be_common {
my ($dst_ref, $src_refs) = @_;
for my $dst_ref (@$dst_refs) {
return 1 if SvRMAGICAL($dst_ref);
}
for my $src_ref (@$src_refs) {
return 1 if SvGMAGICAL($src_ref);
}
for my $dst_ref (@$dst_refs) {
my $dst_addr = refaddr($dst_ref);
for my $src_ref (@$src_refs) {
return 1 if $dst_addr == refaddr($src_ref);
}
}
return 0;
}
say could_be_common([ \$x, \$y ], [ \$c, \$d ]);