Perl:hash-keys丢失了他们的类信息

Kla*_*aus 4 perl hash class key

我有一个包含X.pm方法的包data_x();
我使用类X的实例作为哈希的键%seen,比方说.
现在这些元素keys %seen似乎已经忘记了他们的祝福:

use X;

my( $x, $y, %seen );

$x = X->new();
$x->data_x( 1 );

print " x:      ", $x, "\n";
print " x.data: ", $x->data_x(), "\n";

$seen{ $x } = 1;
$y = (keys %seen)[0];

print " y:      ", $y, "\n";
print " y.data: ", $y->data_x(), "\n";
Run Code Online (Sandbox Code Playgroud)

这打印:

 x:      X=HASH(0x228fd48)
 x.data: 1
 y:      X=HASH(0x228fd48)
Can't locate object method "data_x" via package "X=HASH(0x228fd48)"
(perhaps you forgot to load "X=HASH(0x228fd48)"?) at test.pl line 15.
Run Code Online (Sandbox Code Playgroud)

双方$x$y指向同一个地址,但显然keys并没有复制类信息.
为什么会这样?

Thi*_*ilo 7

他们不仅失去了他们的祝福,他们甚至不再是hashrefs.

您只能在Perl中使用字符串作为哈希键.

所有尚未成为字符串的内容都将被制作成字符串.因此,哈希中的键不再是对象,而是字符串'X = HASH(0x228fd48)'(这是打印时带来的祝福hashref).无法从该字符串返回对象(除非您有另一个将这些键映射到原始对象的哈希).

您需要使用唯一标识符作为哈希键.看来你可以使用当前的字符串版本(基本上是一个内存地址)来至少检查对象的身份(该对象在它活着时似乎没有被移动),但我不确定它会有多稳定是(内部对象的一些实现似乎基于这个想法),它并没有给你对象相等性检查.

  • 获取引用的唯一标识符的正确方法是使用Scalar :: Util :: refaddr http://search.cpan.org/~gbarr/Scalar-List-Utils/lib/Scalar/Util.pm (3认同)