perl:为什么Devel :: Refcount :: refcount和Devel :: Peek :: SvREFCNT不一致?

Pet*_*rch 15 perl

我正在阅读如何访问Perl哈希的引用计数?,并有两个Devel::Refcount::refcountDevel::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);
Run Code Online (Sandbox Code Playgroud)

打印出:

Anon ARRAY ARRAY(0x8b10818) has 1/1 reference
Anon ARRAY ARRAY(0x8b10818) now has 2/1 references
Run Code Online (Sandbox Code Playgroud)

注意最后2/1的差异......

(如果事实证明我没有做一些愚蠢的事情,我会添加一个链接,如何访问Perl哈希的引用计数?到这里)

mob*_*mob 9

我不能说我已经完成了所有这一切,但你的问题在perldoc中得到了显着的回答Devel::Refcount

与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;
Run Code Online (Sandbox Code Playgroud)

这会产生输出

            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
Run Code Online (Sandbox Code Playgroud)

在这里,我们看到SvREFCNT()分别计算传入的SV对象的引用数量作为标量值 - $ var或$ othervar,而refcount()计算指向引用对象的引用值的数量 - 在这种情况下匿名ARRAY.

在构造CODE引用之前,$ var和$ othervar的SvREFCNT()都是1,因为它们仅存在于当前词法填充中.匿名ARRAY的refcount()为2,因为$ var和$ othervar都存储了对它的引用.

在构造CODE引用之后,$ var变量现在具有2的SvREFCNT(),因为它也出现在新的匿名CODE块的词法板中.


ike*_*ami 5

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)
Run Code Online (Sandbox Code Playgroud)

Perl提供了一个半受支持的内置Internals::SvREFCNT函数,该函数可用于标量,数组和哈希。

Internals::SvREFCNT(@$anon)返回@$anon自身的引用计数。

该数组由$anon和引用$otherref:2

上面的方法仅适用于标量,数组和散列,并且您需要使用适当的符号。如果您只想传递任意引用,则可以使用:

&Internals::SvREFCNT($anon) + 1返回由引用的引用的引用计数$anon

该数组由$anon和引用$otherref:2