perl:为什么 Devel::Refcount::refcount 和 Devel::Peek::SvREFCNT 不一致? [英] perl: Why do Devel::Refcount::refcount and Devel::Peek::SvREFCNT disagree?

查看:50
本文介绍了perl:为什么 Devel::Refcount::refcount 和 Devel::Peek::SvREFCNT 不一致?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读 我如何访问Perl 哈希的引用计数?,并且建议使用 Devel::Refcount::refcountDevel::Peek::SvREFCNT.>

但它们不会返回相同的引用计数.这是为什么?

这里是 perldoc Devel::Refcount 的修改示例:

use Devel::Peek;使用开发::引用计数;我的 $anon = [];printf "匿名数组 $anon 有 %d/%d 个引用\n",开发::引用计数::引用计数($anon),开发::窥视::SvREFCNT($anon);我的 $otherref = $anon;printf "Anon ARRAY $anon 现在有 %d/%d 个引用\n",开发::引用计数::引用计数($anon),开发::窥视::SvREFCNT($anon);

打印出来:

Anon ARRAY ARRAY(0x8b10818) 有 1/1 引用Anon ARRAY ARRAY(0x8b10818) 现在有 2/1 个引用

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

(如果事实证明我没有做蠢事,我将添加来自 如何访问 Perl 哈希的引用计数? 到这里)

解决方案

我不能说我已经完全理解了,但是您的问题在 Devel::Refcount perldoc

<块引用>

与 SvREFCNT 的比较

此函数与 Devel::Peek::SvREFCNT 的不同之处在于,SvREFCNT() 给出传递的 SV 对象本身的引用计数,而 refcount() 给出所指向对象的计数.这允许它也给出任何引用的计数(即 ARRAY、HASH、CODE、GLOB 和 Regexp 类型).

考虑以下示例程序:

 使用 Devel::Peek qw( SvREFCNT );使用 Devel::Refcount qw( refcount );子打印计数{我的 $name = shift;printf "%30s 有 SvREFCNT=%d, refcount=%d\n",$name, SvREFCNT($_[0]), refcount($_[0]);}我的 $var = [];printcount '最初,$var',$var;我的 $othervar = $var;printcount '在代码引用之前,$var',$var;打印计数 '$othervar', $othervar;我的 $code = sub { undef $var };printcount '在代码引用之后,$var',$var;打印计数 '$othervar', $othervar;

<块引用>

这会产生输出

 最初,$var 有 SvREFCNT=1,refcount=1在 CODE ref 之前,$var 有 SvREFCNT=1,refcount=2$othervar 有 SvREFCNT=1,refcount=2在 CODE ref 之后,$var 有 SvREFCNT=2, refcount=2$othervar 有 SvREFCNT=1,refcount=2

<块引用>

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

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

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

I was reading How can I access the ref count of a Perl hash?, and there both Devel::Refcount::refcount and Devel::Peek::SvREFCNT are suggested.

But they don't return the same reference counts. Why is that?

Here a modified example from 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);

which prints out:

Anon ARRAY ARRAY(0x8b10818) has 1/1 reference
Anon ARRAY ARRAY(0x8b10818) now has 2/1 references

Notice the last 2/1 discrepancy...

(If it turns out I'm not doing something stupid, I'll add a link from How can I access the ref count of a Perl hash? to here)

解决方案

I can't say that I grok all of it yet, but your question is answered prominently in the Devel::Refcount perldoc

COMPARISON WITH SvREFCNT

This function differs from Devel::Peek::SvREFCNT in that SvREFCNT() gives the reference count of the SV object itself that it is passed, whereas refcount() gives the count of the object being pointed to. This allows it to give the count of any referent (i.e. ARRAY, HASH, CODE, GLOB and Regexp types) as well.

Consider the following example program:

 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;

This produces the output

            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

Here, we see that SvREFCNT() counts the number of references to the SV object passed in as the scalar value - the $var or $othervar respectively, whereas refcount() counts the number of reference values that point to the referent object - the anonymous ARRAY in this case.

Before the CODE reference is constructed, both $var and $othervar have SvREFCNT() of 1, as they exist only in the current lexical pad. The anonymous ARRAY has a refcount() of 2, because both $var and $othervar store a reference to it.

After the CODE reference is constructed, the $var variable now has an SvREFCNT() of 2, because it also appears in the lexical pad for the new anonymous CODE block.

这篇关于perl:为什么 Devel::Refcount::refcount 和 Devel::Peek::SvREFCNT 不一致?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆