我正在阅读How can I access the ref count of a Perl hash?,并建议Devel::Refcount::refcount
和Devel::Peek::SvREFCNT
。
但他们没有返回相同的引用计数。那是为什么?
这是perldoc Devel::Refcount
的修改示例:
use Devel::Peek;
use Devel::Refcount;
my $anon = [];
printf "Anon ARRAY $anon has %d/%d reference\n",
Devel::Refcount::refcount($anon),
Devel::Peek::SvREFCNT($anon);
my $otherref = $anon;
printf "Anon ARRAY $anon now has %d/%d references\n",
Devel::Refcount::refcount($anon),
Devel::Peek::SvREFCNT($anon);
打印出来:
Anon ARRAY ARRAY(0x8b10818) has 1/1 reference
Anon ARRAY ARRAY(0x8b10818) now has 2/1 references
注意最后2/1的差异......
(如果事实证明我没有做一些愚蠢的事情,我会在How can I access the ref count of a Perl hash?添加一个链接到这里)
答案 0 :(得分:8)
我不能说我已经完成了所有这些,但你的问题在Devel::Refcount
perldoc
与SvREFCNT比较
此函数与Devel :: Peek :: SvREFCNT的不同之处在于,SvREFCNT()给出了传递它的SV对象本身的引用计数,而refcount()给出了指向的对象的计数。这允许它给出任何指示对象的计数(即ARRAY,HASH,CODE,GLOB和Regexp类型)。
考虑以下示例程序:
use Devel::Peek qw( SvREFCNT );
use Devel::Refcount qw( refcount );
sub printcount
{
my $name = shift;
printf "%30s has SvREFCNT=%d, refcount=%d\n",
$name, SvREFCNT($_[0]), refcount($_[0]);
}
my $var = [];
printcount 'Initially, $var', $var;
my $othervar = $var;
printcount 'Before CODE ref, $var', $var;
printcount '$othervar', $othervar;
my $code = sub { undef $var };
printcount 'After CODE ref, $var', $var;
printcount '$othervar', $othervar;
这会产生输出
Initially, $var has SvREFCNT=1, refcount=1
Before CODE ref, $var has SvREFCNT=1, refcount=2
$othervar has SvREFCNT=1, refcount=2
After CODE ref, $var has SvREFCNT=2, refcount=2
$othervar has SvREFCNT=1, refcount=2
在这里,我们看到SvREFCNT()将传入的SV对象的引用数分别计算为标量值 - $ var或$ othervar,而refcount()计算指向引用的引用值的数量object - 在这种情况下是匿名ARRAY。
在构造CODE引用之前,$ var和$ othervar的SvREFCNT()都是1,因为它们仅存在于当前词法填充中。匿名ARRAY的refcount()为2,因为$ var和$ othervar都存储了对它的引用。
构造CODE引用之后,$ var变量现在的SvREFCNT()为2,因为它也出现在新的匿名CODE块的词法填充中。
答案 1 :(得分:4)
Devel::Refcount::refcount($anon)
返回$anon
引用的引用计数。
数组由$anon
和$otherref
引用:2
Devel::Peek::SvREFCNT($anon)
会返回$anon
本身的引用计数。
标量由它所在的垫子引用:1
Devel :: Peek似乎没有提供获取数组,散列等的引用计数的方法。
$ perl -MDevel::Peek -E'my $aref2 = my $aref1 = []; Dump($aref1);'
SV = IV(0x99eee34) at 0x99eee38
REFCNT = 1 <---- Devel::Peek::SvREFCNT
FLAGS = (PADMY,ROK)
RV = 0x99d57d0
SV = PVAV(0x99d6778) at 0x99d57d0
REFCNT = 2 <---- Devel::Refcount::refcount
FLAGS = ()
ARRAY = 0x0
FILL = -1
MAX = -1
ARYLEN = 0x0
FLAGS = (REAL)
Perl提供了一个名为Internals::SvREFCNT
的半支持内置函数,可用于标量,数组和哈希。
Internals::SvREFCNT(@$anon)
会返回@$anon
本身的引用计数。
数组由$anon
和$otherref
引用:2
以上仅适用于标量,数组和散列,您需要使用正确的标记。如果您只想传递任意引用,可以使用:
&Internals::SvREFCNT($anon) + 1
返回$anon
引用的引用计数。
数组由$anon
和$otherref
引用:2