根据Scalar :: Util的文档,refaddr工作方式如下:
Run Code Online (Sandbox Code Playgroud)my $addr = refaddr( $ref );如果引用$ ref,则引用值的内部存储器地址将作为普通整数返回.否则返回undef.
但是,这并不能告诉我是否$addr是永久性的.可以在refaddr一段时间内参考的变化?例如,在C中,运行realloc可以改变存储在动态存储器中的东西的位置.这与Perl 5类似吗?
我问,因为我想制作一个由内而外的对象,我想知道是否refaddr($object)能成为一把好钥匙.例如,在XS中编程时似乎最简单.
首先,不要重新发明轮子; 使用Class :: InsideOut.
这是永久性的.必须是,否则以下会失败:
my $x;
my $r = \$x;
... Do something with $x ...
say $$r;
Run Code Online (Sandbox Code Playgroud)
标量在固定位置有"头".如果SV需要升级(例如,保持字符串),那么它就是第二个被称为"正文"的内存块,它将发生变化.字符串缓冲区是第三个内存块.

$ perl -MDevel::Peek -MScalar::Util=refaddr -E'
my $x=4;
my $r=\$x;
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
say "";
say "Upgrade SV:";
$x='abc';
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
say "";
say "Increase PV size:";
$x="x"x20;
say sprintf "refaddr=0x%x", refaddr($r);
Dump($$r);
'
Run Code Online (Sandbox Code Playgroud)
refaddr=0x2e1db58
SV = IV(0x2e1db48) at 0x2e1db58 <-- SVt_IV variables can't hold strings.
REFCNT = 2
FLAGS = (PADMY,IOK,pIOK)
IV = 4
Upgrade SV:
refaddr=0x2e1db58
SV = PVIV(0x2e18b40) at 0x2e1db58 <-- Scalar upgrade to SVt_PVIV.
REFCNT = 2 New body at new address,
FLAGS = (PADMY,POK,IsCOW,pPOK) but head still at same address.
IV = 4
PV = 0x2e86f20 "abc"\0 <-- The scalar now has a string buffer.
CUR = 3
LEN = 10
COW_REFCNT = 1
Increase PV size:
refaddr=0x2e1db58
SV = PVIV(0x2e18b40) at 0x2e1db58
REFCNT = 2
FLAGS = (PADMY,POK,pPOK)
IV = 4
PV = 0x2e5d7b0 "xxxxxxxxxxxxxxxxxxxx"\0 <-- Changing the address of the string buffer
REFCNT = 2 doesn't change anything else.
CUR = 20
LEN = 22
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
173 次 |
| 最近记录: |